⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 pkinit.c

📁 samba最新软件
💻 C
📖 第 1 页 / 共 4 页
字号:
/* * Copyright (c) 2003 - 2007 Kungliga Tekniska H鰃skolan * (Royal Institute of Technology, Stockholm, Sweden).  * All rights reserved.  * * Redistribution and use in source and binary forms, with or without  * modification, are permitted provided that the following conditions  * are met:  * * 1. Redistributions of source code must retain the above copyright  *    notice, this list of conditions and the following disclaimer.  * * 2. Redistributions in binary form must reproduce the above copyright  *    notice, this list of conditions and the following disclaimer in the  *    documentation and/or other materials provided with the distribution.  * * 3. Neither the name of the Institute nor the names of its contributors  *    may be used to endorse or promote products derived from this software  *    without specific prior written permission.  * * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE  * ARE DISCLAIMED.  IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF  * SUCH DAMAGE.  */#include "krb5_locl.h"RCSID("$Id: pkinit.c 22673 2008-03-10 15:00:05Z lha $");struct krb5_dh_moduli {    char *name;    unsigned long bits;    heim_integer p;    heim_integer g;    heim_integer q;};#ifdef PKINIT#include <heim_asn1.h>#include <rfc2459_asn1.h>#include <cms_asn1.h>#include <pkcs8_asn1.h>#include <pkcs9_asn1.h>#include <pkcs12_asn1.h>#include <pkinit_asn1.h>#include <asn1_err.h>#include <der.h>#include <hx509.h>enum {    COMPAT_WIN2K = 1,    COMPAT_IETF = 2};struct krb5_pk_identity {    hx509_context hx509ctx;    hx509_verify_ctx verify_ctx;    hx509_certs certs;    hx509_certs anchors;    hx509_certs certpool;    hx509_revoke_ctx revokectx;};struct krb5_pk_cert {    hx509_cert cert;};struct krb5_pk_init_ctx_data {    struct krb5_pk_identity *id;    DH *dh;    krb5_data *clientDHNonce;    struct krb5_dh_moduli **m;    hx509_peer_info peer;    int type;    unsigned int require_binding:1;    unsigned int require_eku:1;    unsigned int require_krbtgt_otherName:1;    unsigned int require_hostname_match:1;    unsigned int trustedCertifiers:1;};static void_krb5_pk_copy_error(krb5_context context,		    hx509_context hx509ctx,		    int hxret,		    const char *fmt,		    ...)    __attribute__ ((format (printf, 4, 5)));/* * */void KRB5_LIB_FUNCTION_krb5_pk_cert_free(struct krb5_pk_cert *cert){    if (cert->cert) {	hx509_cert_free(cert->cert);    }    free(cert);}static krb5_error_codeBN_to_integer(krb5_context context, BIGNUM *bn, heim_integer *integer){    integer->length = BN_num_bytes(bn);    integer->data = malloc(integer->length);    if (integer->data == NULL) {	krb5_clear_error_string(context);	return ENOMEM;    }    BN_bn2bin(bn, integer->data);    integer->negative = BN_is_negative(bn);    return 0;}static BIGNUM *integer_to_BN(krb5_context context, const char *field, const heim_integer *f){    BIGNUM *bn;    bn = BN_bin2bn((const unsigned char *)f->data, f->length, NULL);    if (bn == NULL) {	krb5_set_error_string(context, "PKINIT: parsing BN failed %s", field);	return NULL;    }    BN_set_negative(bn, f->negative);    return bn;}struct certfind {    const char *type;    const heim_oid *oid;};/* * Try searchin the key by to use by first looking for for PK-INIT * EKU, then the Microsoft smart card EKU and last, no special EKU at all. */static krb5_error_codefind_cert(krb5_context context, struct krb5_pk_identity *id, 	  hx509_query *q, hx509_cert *cert){    struct certfind cf[3] = { 	{ "PKINIT EKU" },	{ "MS EKU" },	{ "no" }    };    int i, ret;    cf[0].oid = oid_id_pkekuoid();    cf[1].oid = oid_id_pkinit_ms_eku();    cf[2].oid = NULL;    for (i = 0; i < sizeof(cf)/sizeof(cf[0]); i++) {	ret = hx509_query_match_eku(q, cf[i].oid);	if (ret) {	    _krb5_pk_copy_error(context, id->hx509ctx, ret, 				"Failed setting %s OID", cf[i].type);	    return ret;	}	ret = hx509_certs_find(id->hx509ctx, id->certs, q, cert);	if (ret == 0)	    break;	_krb5_pk_copy_error(context, id->hx509ctx, ret, 			    "Failed cert for finding %s OID", cf[i].type);    }    return ret;}static krb5_error_codecreate_signature(krb5_context context,		 const heim_oid *eContentType,		 krb5_data *eContent,		 struct krb5_pk_identity *id,		 hx509_peer_info peer,		 krb5_data *sd_data){    hx509_cert cert = NULL;    hx509_query *q = NULL;    int ret;    ret = hx509_query_alloc(id->hx509ctx, &q);    if (ret) {	_krb5_pk_copy_error(context, id->hx509ctx, ret, 			    "Allocate query to find signing certificate");	return ret;    }    hx509_query_match_option(q, HX509_QUERY_OPTION_PRIVATE_KEY);    hx509_query_match_option(q, HX509_QUERY_OPTION_KU_DIGITALSIGNATURE);    ret = find_cert(context, id, q, &cert);    hx509_query_free(id->hx509ctx, q);    if (ret)	return ret;    ret = hx509_cms_create_signed_1(id->hx509ctx,				    0,				    eContentType,				    eContent->data,				    eContent->length,				    NULL,				    cert,				    peer,				    NULL,				    id->certs,				    sd_data);    hx509_cert_free(cert);    if (ret) {	_krb5_pk_copy_error(context, id->hx509ctx, ret,			    "Create CMS signedData");	return ret;    }    return 0;}static intcert2epi(hx509_context context, void *ctx, hx509_cert c){    ExternalPrincipalIdentifiers *ids = ctx;    ExternalPrincipalIdentifier id;    hx509_name subject = NULL;    void *p;    int ret;    memset(&id, 0, sizeof(id));    ret = hx509_cert_get_subject(c, &subject);    if (ret)	return ret;    if (hx509_name_is_null_p(subject) != 0) {	id.subjectName = calloc(1, sizeof(*id.subjectName));	if (id.subjectName == NULL) {	    hx509_name_free(&subject);	    free_ExternalPrincipalIdentifier(&id);	    return ENOMEM;	}    	ret = hx509_name_binary(subject, id.subjectName);	if (ret) {	    hx509_name_free(&subject);	    free_ExternalPrincipalIdentifier(&id);	    return ret;	}    }    hx509_name_free(&subject);    id.issuerAndSerialNumber = calloc(1, sizeof(*id.issuerAndSerialNumber));    if (id.issuerAndSerialNumber == NULL) {	free_ExternalPrincipalIdentifier(&id);	return ENOMEM;    }    {	IssuerAndSerialNumber iasn;	hx509_name issuer;	size_t size;		memset(&iasn, 0, sizeof(iasn));	ret = hx509_cert_get_issuer(c, &issuer);	if (ret) {	    free_ExternalPrincipalIdentifier(&id);	    return ret;	}	ret = hx509_name_to_Name(issuer, &iasn.issuer);	hx509_name_free(&issuer);	if (ret) {	    free_ExternalPrincipalIdentifier(&id);	    return ret;	}		ret = hx509_cert_get_serialnumber(c, &iasn.serialNumber);	if (ret) {	    free_IssuerAndSerialNumber(&iasn);	    free_ExternalPrincipalIdentifier(&id);	    return ret;	}	ASN1_MALLOC_ENCODE(IssuerAndSerialNumber,			   id.issuerAndSerialNumber->data, 			   id.issuerAndSerialNumber->length,			   &iasn, &size, ret);	free_IssuerAndSerialNumber(&iasn);	if (ret)	    return ret;	if (id.issuerAndSerialNumber->length != size)	    abort();    }    id.subjectKeyIdentifier = NULL;    p = realloc(ids->val, sizeof(ids->val[0]) * (ids->len + 1));     if (p == NULL) {	free_ExternalPrincipalIdentifier(&id);	return ENOMEM;    }    ids->val = p;    ids->val[ids->len] = id;    ids->len++;    return 0;}static krb5_error_codebuild_edi(krb5_context context,	  hx509_context hx509ctx,	  hx509_certs certs,	  ExternalPrincipalIdentifiers *ids){    return hx509_certs_iter(hx509ctx, certs, cert2epi, ids);}static krb5_error_codebuild_auth_pack(krb5_context context,		unsigned nonce,		krb5_pk_init_ctx ctx,		DH *dh,		const KDC_REQ_BODY *body,		AuthPack *a){    size_t buf_size, len;    krb5_error_code ret;    void *buf;    krb5_timestamp sec;    int32_t usec;    Checksum checksum;    krb5_clear_error_string(context);    memset(&checksum, 0, sizeof(checksum));    krb5_us_timeofday(context, &sec, &usec);    a->pkAuthenticator.ctime = sec;    a->pkAuthenticator.nonce = nonce;    ASN1_MALLOC_ENCODE(KDC_REQ_BODY, buf, buf_size, body, &len, ret);    if (ret)	return ret;    if (buf_size != len)	krb5_abortx(context, "internal error in ASN.1 encoder");    ret = krb5_create_checksum(context,			       NULL,			       0,			       CKSUMTYPE_SHA1,			       buf,			       len,			       &checksum);    free(buf);    if (ret) 	return ret;    ALLOC(a->pkAuthenticator.paChecksum, 1);    if (a->pkAuthenticator.paChecksum == NULL) {	krb5_set_error_string(context, "malloc: out of memory");	return ENOMEM;    }    ret = krb5_data_copy(a->pkAuthenticator.paChecksum,			 checksum.checksum.data, checksum.checksum.length);    free_Checksum(&checksum);    if (ret)	return ret;    if (dh) {	DomainParameters dp;	heim_integer dh_pub_key;	krb5_data dhbuf;	size_t size;	if (1 /* support_cached_dh */) {	    ALLOC(a->clientDHNonce, 1);	    if (a->clientDHNonce == NULL) {		krb5_clear_error_string(context);		return ENOMEM;	    }	    ret = krb5_data_alloc(a->clientDHNonce, 40);	    if (a->clientDHNonce == NULL) {		krb5_clear_error_string(context);		return ENOMEM;	    }	    memset(a->clientDHNonce->data, 0, a->clientDHNonce->length);	    ret = krb5_copy_data(context, a->clientDHNonce, 				 &ctx->clientDHNonce);	    if (ret)		return ret;	}	ALLOC(a->clientPublicValue, 1);	if (a->clientPublicValue == NULL)	    return ENOMEM;	ret = der_copy_oid(oid_id_dhpublicnumber(),			   &a->clientPublicValue->algorithm.algorithm);	if (ret)	    return ret;		memset(&dp, 0, sizeof(dp));	ret = BN_to_integer(context, dh->p, &dp.p);	if (ret) {	    free_DomainParameters(&dp);	    return ret;	}	ret = BN_to_integer(context, dh->g, &dp.g);	if (ret) {	    free_DomainParameters(&dp);	    return ret;	}	ret = BN_to_integer(context, dh->q, &dp.q);	if (ret) {	    free_DomainParameters(&dp);	    return ret;	}	dp.j = NULL;	dp.validationParms = NULL;	a->clientPublicValue->algorithm.parameters = 	    malloc(sizeof(*a->clientPublicValue->algorithm.parameters));	if (a->clientPublicValue->algorithm.parameters == NULL) {	    free_DomainParameters(&dp);	    return ret;	}	ASN1_MALLOC_ENCODE(DomainParameters,			   a->clientPublicValue->algorithm.parameters->data,			   a->clientPublicValue->algorithm.parameters->length,			   &dp, &size, ret);	free_DomainParameters(&dp);	if (ret)	    return ret;	if (size != a->clientPublicValue->algorithm.parameters->length)	    krb5_abortx(context, "Internal ASN1 encoder error");	ret = BN_to_integer(context, dh->pub_key, &dh_pub_key);	if (ret)	    return ret;	ASN1_MALLOC_ENCODE(DHPublicKey, dhbuf.data, dhbuf.length,			   &dh_pub_key, &size, ret);	der_free_heim_integer(&dh_pub_key);	if (ret)	    return ret;	if (size != dhbuf.length)	    krb5_abortx(context, "asn1 internal error");	a->clientPublicValue->subjectPublicKey.length = dhbuf.length * 8;	a->clientPublicValue->subjectPublicKey.data = dhbuf.data;    }    {	a->supportedCMSTypes = calloc(1, sizeof(*a->supportedCMSTypes));	if (a->supportedCMSTypes == NULL)	    return ENOMEM;	ret = hx509_crypto_available(ctx->id->hx509ctx, HX509_SELECT_ALL, NULL,				     &a->supportedCMSTypes->val,				     &a->supportedCMSTypes->len);	if (ret)	    return ret;    }    return ret;}krb5_error_code KRB5_LIB_FUNCTION_krb5_pk_mk_ContentInfo(krb5_context context,			const krb5_data *buf, 			const heim_oid *oid,			struct ContentInfo *content_info){    krb5_error_code ret;    ret = der_copy_oid(oid, &content_info->contentType);    if (ret)	return ret;    ALLOC(content_info->content, 1);    if (content_info->content == NULL)	return ENOMEM;    content_info->content->data = malloc(buf->length);    if (content_info->content->data == NULL)	return ENOMEM;    memcpy(content_info->content->data, buf->data, buf->length);    content_info->content->length = buf->length;    return 0;}static krb5_error_codepk_mk_padata(krb5_context context,	     krb5_pk_init_ctx ctx,	     const KDC_REQ_BODY *req_body,	     unsigned nonce,	     METHOD_DATA *md){    struct ContentInfo content_info;    krb5_error_code ret;    const heim_oid *oid;    size_t size;    krb5_data buf, sd_buf;    int pa_type;    krb5_data_zero(&buf);    krb5_data_zero(&sd_buf);    memset(&content_info, 0, sizeof(content_info));    if (ctx->type == COMPAT_WIN2K) {	AuthPack_Win2k ap;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -