コード例 #1
0
/*
 * Decode a KRB5_PA_PK_AS_REP.
 */
krb5_error_code krb5int_pkinit_pa_pk_as_rep_decode(
    const krb5_data *pa_pk_as_rep,
    krb5_data *dh_signed_data,
    krb5_data *enc_key_pack)
{
    KRB5_PA_PK_AS_REP asRep;
    SecAsn1CoderRef coder;
    CSSM_DATA der = {pa_pk_as_rep->length, (uint8 *)pa_pk_as_rep->data};
    krb5_error_code ourRtn = 0;

    /* Decode --> KRB5_PA_PK_AS_REP */
    if(SecAsn1CoderCreate(&coder)) {
	return ENOMEM;
    }
    memset(&asRep, 0, sizeof(asRep));
    if(SecAsn1DecodeData(coder, &der, KRB5_PA_PK_AS_REPTemplate, &asRep)) {
	ourRtn = ASN1_BAD_FORMAT;
	goto errOut;
    }

    if(asRep.dhSignedData) {
	if((ourRtn = pkiCssmDataToKrb5Data(asRep.dhSignedData, dh_signed_data))) {
	    goto errOut;
	}
    }
    if(asRep.encKeyPack) {
	ourRtn = pkiCssmDataToKrb5Data(asRep.encKeyPack, enc_key_pack);
    }

errOut:
    SecAsn1CoderRelease(coder);
    return ourRtn;
}
コード例 #2
0
/*
 * Decode IssuerAndSerialNumber.
 */
krb5_error_code krb5int_pkinit_issuer_serial_decode(
    const krb5_data *issuer_and_serial,     /* DER encoded */
    krb5_data       *issuer,		    /* DER encoded, RETURNED */
    krb5_data       *serial_num)	    /* RETURNED */
{
    KRB5_IssuerAndSerial issuerSerial;
    SecAsn1CoderRef coder;
    CSSM_DATA der = {issuer_and_serial->length, (uint8 *)issuer_and_serial->data};
    krb5_error_code ourRtn = 0;

    /* Decode --> issuerSerial */
    if(SecAsn1CoderCreate(&coder)) {
	return ENOMEM;
    }
    memset(&issuerSerial, 0, sizeof(issuerSerial));
    if(SecAsn1DecodeData(coder, &der, KRB5_IssuerAndSerialTemplate, &issuerSerial)) {
	ourRtn = ASN1_BAD_FORMAT;
	goto errOut;
    }

    /* Convert KRB5_IssuerAndSerial to caller's params */
    if((ourRtn = pkiCssmDataToKrb5Data(&issuerSerial.derIssuer, issuer))) {
	goto errOut;
    }
    if((ourRtn = pkiCssmDataToKrb5Data(&issuerSerial.serialNumber, serial_num))) {
	ourRtn = ENOMEM;
	goto errOut;
    }

errOut:
    SecAsn1CoderRelease(coder);
    return ourRtn;
}
コード例 #3
0
/*
 * Given DER-encoded issuer and serial number, create an encoded
 * IssuerAndSerialNumber.
 */
krb5_error_code krb5int_pkinit_issuer_serial_encode(
    const krb5_data *issuer,		    /* DER encoded */
    const krb5_data *serial_num,
    krb5_data       *issuer_and_serial)     /* content mallocd and RETURNED */
{
    KRB5_IssuerAndSerial issuerSerial;
    SecAsn1CoderRef coder;
    CSSM_DATA ber = {0, NULL};
    OSStatus ortn;

    if(SecAsn1CoderCreate(&coder)) {
	return ENOMEM;
    }
    PKI_KRB_TO_CSSM_DATA(issuer, &issuerSerial.derIssuer);
    PKI_KRB_TO_CSSM_DATA(serial_num, &issuerSerial.serialNumber);
    ortn = SecAsn1EncodeItem(coder, &issuerSerial, KRB5_IssuerAndSerialTemplate, &ber);
    if(ortn) {
	ortn = ENOMEM;
	goto errOut;
    }
    ortn = pkiCssmDataToKrb5Data(&ber, issuer_and_serial);
errOut:
    SecAsn1CoderRelease(coder);
    return ortn;
}
コード例 #4
0
ファイル: pkinit_apple_cms.c プロジェクト: aosm/Kerberos
/*
 * Convert CFArray of SecCertificateRefs to a mallocd array of krb5_datas.
 */
static krb5_error_code pkiCertArrayToKrb5Data(
    CFArrayRef  cf_certs,
    unsigned	*num_all_certs,
    krb5_data   **all_certs)	
{
    CFIndex num_certs;
    krb5_data *allCerts = NULL;
    krb5_error_code krtn = 0;
    unsigned dex;
    
    if(cf_certs == NULL) {
	*all_certs = NULL;
	return 0;
    }
    num_certs = CFArrayGetCount(cf_certs);
    *num_all_certs = (unsigned)num_certs;
    if(num_certs == 0) {
	*all_certs = NULL;
	return 0;
    }
    allCerts = (krb5_data *)malloc(sizeof(krb5_data) * num_certs);
    if(allCerts == NULL) {
	return ENOMEM;
    }
    for(dex=0; dex<num_certs; dex++) {	
	CSSM_DATA cert_data;
	OSStatus ortn;
	SecCertificateRef sec_cert;
	
	sec_cert = (SecCertificateRef)CFArrayGetValueAtIndex(cf_certs, dex);
	ortn = SecCertificateGetData(sec_cert, &cert_data);
	if(ortn) {
	    pkiCssmErr("SecCertificateGetData", ortn);
	    krtn = KRB5_PARSE_MALFORMED;
	    break;
	}
	krtn = pkiCssmDataToKrb5Data(&cert_data, &allCerts[dex]);
	if(krtn) {
	    break;
	}
    }
    if(krtn) {
	if(allCerts) {
	    free(allCerts);
	}
    }
    else {
	*all_certs = allCerts;
    }
    return krtn;
}
コード例 #5
0
/*
 * Decode a ReplyKeyPack.
 */
krb5_error_code krb5int_pkinit_reply_key_pack_decode(
    const krb5_data	*reply_key_pack,
    krb5_keyblock       *key_block,     /* RETURNED */
    krb5_checksum	*checksum)	/* contents mallocd and RETURNED */
{
    KRB5_ReplyKeyPack repKeyPack;
    SecAsn1CoderRef coder;
    krb5_error_code ourRtn = 0;
    KRB5_EncryptionKey *encryptKey = &repKeyPack.encryptionKey;
    CSSM_DATA der = {reply_key_pack->length, (uint8 *)reply_key_pack->data};
    krb5_data tmpData;
    KRB5_Checksum *cksum = &repKeyPack.asChecksum;

    /* Decode --> KRB5_ReplyKeyPack */
    if(SecAsn1CoderCreate(&coder)) {
	return ENOMEM;
    }
    memset(&repKeyPack, 0, sizeof(repKeyPack));
    if(SecAsn1DecodeData(coder, &der, KRB5_ReplyKeyPackTemplate, &repKeyPack)) {
	ourRtn = ASN1_BAD_FORMAT;
	goto errOut;
    }

    if((ourRtn = pkiDataToInt(&encryptKey->keyType, (krb5_int32 *)&key_block->enctype))) {
	goto errOut;
    }
    if((ourRtn = pkiCssmDataToKrb5Data(&encryptKey->keyValue, &tmpData))) {
	goto errOut;
    }
    key_block->contents = (krb5_octet *)tmpData.data;
    key_block->length = tmpData.length;

    if((ourRtn = pkiDataToInt(&cksum->checksumType, &checksum->checksum_type))) {
	goto errOut;
    }
    checksum->contents = (krb5_octet *)malloc(cksum->checksum.Length);
    if(checksum->contents == NULL) {
	ourRtn = ENOMEM;
	goto errOut;
    }
    checksum->length = cksum->checksum.Length;
    memmove(checksum->contents, cksum->checksum.Data, checksum->length);
    checksum->magic = KV5M_CHECKSUM;

errOut:
    SecAsn1CoderRelease(coder);
    return ourRtn;
}
コード例 #6
0
/*
 * Encode a ReplyKeyPack. The result is used as the Content of a SignedData.
 */
krb5_error_code krb5int_pkinit_reply_key_pack_encode(
    const krb5_keyblock *key_block,
    const krb5_checksum *checksum,
    krb5_data		*reply_key_pack)      /* mallocd and RETURNED */
{
    KRB5_ReplyKeyPack repKeyPack;
    SecAsn1CoderRef coder;
    krb5_error_code ourRtn = 0;
    CSSM_DATA der = {0, NULL};
    OSStatus ortn;
    KRB5_EncryptionKey *encryptKey = &repKeyPack.encryptionKey;
    KRB5_Checksum *cksum = &repKeyPack.asChecksum;

    if(SecAsn1CoderCreate(&coder)) {
	return ENOMEM;
    }
    memset(&repKeyPack, 0, sizeof(repKeyPack));

    if((ourRtn = pkiIntToData(key_block->enctype, &encryptKey->keyType, coder))) {
	goto errOut;
    }
    encryptKey->keyValue.Length = key_block->length,
    encryptKey->keyValue.Data = (uint8 *)key_block->contents;

    if((ourRtn = pkiIntToData(checksum->checksum_type, &cksum->checksumType, coder))) {
	goto errOut;
    }
    cksum->checksum.Data = (uint8 *)checksum->contents;
    cksum->checksum.Length = checksum->length;

    ortn = SecAsn1EncodeItem(coder, &repKeyPack, KRB5_ReplyKeyPackTemplate, &der);
    if(ortn) {
	ourRtn = ENOMEM;
	goto errOut;
    }
    ourRtn = pkiCssmDataToKrb5Data(&der, reply_key_pack);
errOut:
    SecAsn1CoderRelease(coder);
    return ourRtn;
}
コード例 #7
0
/*
 * Encode a KRB5_PA_PK_AS_REP.
 */
krb5_error_code krb5int_pkinit_pa_pk_as_rep_encode(
    const krb5_data *dh_signed_data,
    const krb5_data *enc_key_pack,
    krb5_data       *pa_pk_as_rep)      /* mallocd and RETURNED */
{
    KRB5_PA_PK_AS_REP asRep;
    SecAsn1CoderRef coder;
    krb5_error_code ourRtn = 0;
    CSSM_DATA	    der = {0, NULL};
    OSStatus	    ortn;
    CSSM_DATA	    dhSignedData;
    CSSM_DATA	    encKeyPack;

    if(SecAsn1CoderCreate(&coder)) {
	return ENOMEM;
    }
    memset(&asRep, 0, sizeof(asRep));
    if(dh_signed_data) {
	PKI_KRB_TO_CSSM_DATA(dh_signed_data, &dhSignedData);
	asRep.dhSignedData = &dhSignedData;
    }
    if(enc_key_pack) {
	PKI_KRB_TO_CSSM_DATA(enc_key_pack, &encKeyPack);
	asRep.encKeyPack = &encKeyPack;
    }

    ortn = SecAsn1EncodeItem(coder, &asRep, KRB5_PA_PK_AS_REPTemplate, &der);
    if(ortn) {
	ourRtn = ENOMEM;
	goto errOut;
    }
    ourRtn = pkiCssmDataToKrb5Data(&der, pa_pk_as_rep);

errOut:
    SecAsn1CoderRelease(coder);
    return ourRtn;
}
コード例 #8
0
/*
 * Top-level decode for PA-PK-AS-REQ.
 */
krb5_error_code krb5int_pkinit_pa_pk_as_req_decode(
    const krb5_data *pa_pk_as_req,
    krb5_data *signed_auth_pack,	    /* DER encoded ContentInfo, RETURNED */
    /*
     * Remainder are optionally RETURNED (specify NULL for pointers to
     * items you're not interested in).
     */
    krb5_ui_4 *num_trusted_CAs,     /* sizeof trusted_CAs */
    krb5_data **trusted_CAs,	    /* mallocd array of DER-encoded TrustedCAs issuer/serial */
    krb5_data *kdc_cert)	    /* DER encoded issuer/serial */
{
    KRB5_PA_PK_AS_REQ asReq;
    SecAsn1CoderRef coder;
    CSSM_DATA der;
    krb5_error_code ourRtn = 0;

    assert(pa_pk_as_req != NULL);

    /* Decode --> KRB5_PA_PK_AS_REQ */
    if(SecAsn1CoderCreate(&coder)) {
	return ENOMEM;
    }
    PKI_KRB_TO_CSSM_DATA(pa_pk_as_req, &der);
    memset(&asReq, 0, sizeof(asReq));
    if(SecAsn1DecodeData(coder, &der, KRB5_PA_PK_AS_REQTemplate, &asReq)) {
	ourRtn = ASN1_BAD_FORMAT;
	goto errOut;
    }

    /* Convert decoded results to caller's args; each is optional */
    if(signed_auth_pack != NULL) {
	if((ourRtn = pkiCssmDataToKrb5Data(&asReq.signedAuthPack, signed_auth_pack))) {
	    goto errOut;
	}
    }
    if(asReq.trusted_CAs && (trusted_CAs != NULL)) {
	/* NULL-terminated array of CSSM_DATA ptrs */
	unsigned numCas = pkiNssArraySize((const void **)asReq.trusted_CAs);
	unsigned dex;
	krb5_data *kdcCas;

	kdcCas = (krb5_data *)malloc(sizeof(krb5_data) * numCas);
	if(kdcCas == NULL) {
	    ourRtn = ENOMEM;
	    goto errOut;
	}
	for(dex=0; dex<numCas; dex++) {
	    KRB5_ExternalPrincipalIdentifier *epi = asReq.trusted_CAs[dex];
	    if(epi->issuerAndSerialNumber.Data) {
		/* the only variant we support */
		pkiCssmDataToKrb5Data(&epi->issuerAndSerialNumber, &kdcCas[dex]);
	    }
	}
	*trusted_CAs = kdcCas;
	*num_trusted_CAs = numCas;
    }
    if(asReq.kdcPkId.Data && kdc_cert) {
	if((ourRtn = pkiCssmDataToKrb5Data(&asReq.kdcPkId, kdc_cert))) {
	    goto errOut;
	}
    }
errOut:
    SecAsn1CoderRelease(coder);
    return ourRtn;
}
コード例 #9
0
/*
 * Top-level encode for PA-PK-AS-REQ.
 */
krb5_error_code krb5int_pkinit_pa_pk_as_req_encode(
    const krb5_data *signed_auth_pack,      /* DER encoded ContentInfo */
    const krb5_data *trusted_CAs,	    /* optional: trustedCertifiers. Contents are
					     * DER-encoded issuer/serialNumbers. */
    krb5_ui_4	    num_trusted_CAs,
    const krb5_data *kdc_cert,		    /* optional kdcPkId, DER encoded issuer/serial */
    krb5_data	    *pa_pk_as_req)	    /* mallocd and RETURNED */
{
    KRB5_PA_PK_AS_REQ req;
    SecAsn1CoderRef coder;
    CSSM_DATA ber = {0, NULL};
    OSStatus ortn;
    unsigned dex;

    assert(signed_auth_pack != NULL);
    assert(pa_pk_as_req != NULL);

    if(SecAsn1CoderCreate(&coder)) {
	return ENOMEM;
    }

    /* krb5_data ==> CSSM format */

    memset(&req, 0, sizeof(req));
    PKI_KRB_TO_CSSM_DATA(signed_auth_pack, &req.signedAuthPack);
    if(num_trusted_CAs) {
	/*
	 * Set up a NULL-terminated array of KRB5_ExternalPrincipalIdentifier
	 * pointers. We malloc the actual KRB5_ExternalPrincipalIdentifiers as
	 * a contiguous array; it's in temp SecAsn1CoderRef memory. The referents
	 * are just dropped in from the caller's krb5_datas.
	 */
	KRB5_ExternalPrincipalIdentifier *cas =
	    (KRB5_ExternalPrincipalIdentifier *)SecAsn1Malloc(coder,
		num_trusted_CAs * sizeof(KRB5_ExternalPrincipalIdentifier));
	req.trusted_CAs =
	    (KRB5_ExternalPrincipalIdentifier **)
		pkiNssNullArray(num_trusted_CAs, coder);
	for(dex=0; dex<num_trusted_CAs; dex++) {
	    req.trusted_CAs[dex] = &cas[dex];
	    memset(&cas[dex], 0, sizeof(KRB5_ExternalPrincipalIdentifier));
	    PKI_KRB_TO_CSSM_DATA(&trusted_CAs[dex],
		&cas[dex].issuerAndSerialNumber);
	}
    }
    if(kdc_cert) {
	PKI_KRB_TO_CSSM_DATA(kdc_cert, &req.kdcPkId);
    }

    /* encode */
    ortn = SecAsn1EncodeItem(coder, &req, KRB5_PA_PK_AS_REQTemplate, &ber);
    if(ortn) {
	ortn = ENOMEM;
	goto errOut;
    }
    ortn = pkiCssmDataToKrb5Data(&ber, pa_pk_as_req);

errOut:
    SecAsn1CoderRelease(coder);
    return ortn;
}
コード例 #10
0
/*
 * Decode AuthPack, public key version (no Diffie-Hellman components).
 */
krb5_error_code krb5int_pkinit_auth_pack_decode(
    const krb5_data	*auth_pack,     /* DER encoded */
    krb5_timestamp      *kctime,	/* RETURNED */
    krb5_ui_4		*cusec,		/* microseconds, RETURNED */
    krb5_ui_4		*nonce,		/* RETURNED */
    krb5_checksum       *pa_checksum,	/* contents mallocd and RETURNED */
    krb5int_algorithm_id **cms_types,	/* optionally mallocd and RETURNED */
    krb5_ui_4		*num_cms_types)	/* optionally RETURNED */
{
    KRB5_AuthPack localAuthPack;
    SecAsn1CoderRef coder;
    CSSM_DATA der = {0, NULL};
    krb5_error_code ourRtn = 0;
    CSSM_DATA *cksum = &localAuthPack.pkAuth.paChecksum;

    /* Decode --> localAuthPack */
    if(SecAsn1CoderCreate(&coder)) {
	return ENOMEM;
    }
    PKI_KRB_TO_CSSM_DATA(auth_pack, &der);
    memset(&localAuthPack, 0, sizeof(localAuthPack));
    if(SecAsn1DecodeData(coder, &der, KRB5_AuthPackTemplate, &localAuthPack)) {
	ourRtn = ASN1_BAD_FORMAT;
	goto errOut;
    }

    /* optionally Convert KRB5_AuthPack to caller's params */
    if(kctime) {
	if((ourRtn = pkiTimeStrToKrbTimestamp((char *)localAuthPack.pkAuth.kctime.Data,
		localAuthPack.pkAuth.kctime.Length, kctime))) {
	    goto errOut;
	}
    }
    if(cusec) {
	if((ourRtn = pkiDataToInt(&localAuthPack.pkAuth.cusec, (krb5_int32 *)cusec))) {
	    goto errOut;
	}
    }
    if(nonce) {
	if((ourRtn = pkiDataToInt(&localAuthPack.pkAuth.nonce, (krb5_int32 *)nonce))) {
	    goto errOut;
	}
    }
    if(pa_checksum) {
	if(cksum->Length == 0) {
	    /* This is the unique error for "no paChecksum" */
	    ourRtn = KDC_ERR_PA_CHECKSUM_MUST_BE_INCLUDED;
	    goto errOut;
	}
	else {
	    pa_checksum->contents = (krb5_octet *)malloc(cksum->Length);
	    if(pa_checksum->contents == NULL) {
		ourRtn = ENOMEM;
		goto errOut;
	    }
	    pa_checksum->length = cksum->Length;
	    memmove(pa_checksum->contents, cksum->Data, pa_checksum->length);
	    pa_checksum->magic = KV5M_CHECKSUM;
	    /* This used to be encoded with the checksum but no more... */
	    pa_checksum->checksum_type = CKSUMTYPE_NIST_SHA;
	}
    }
    if(cms_types) {
	if(localAuthPack.supportedCMSTypes == NULL) {
	    *cms_types = NULL;
	    *num_cms_types = 0;
	}
	else {
	    /*
	     * Convert NULL-terminated array of CSSM-style algIds to
	     * krb5int_algorithm_ids.
	     */
	    unsigned dex;
	    unsigned num_types = 0;
	    CSSM_X509_ALGORITHM_IDENTIFIER **alg_ids;
	    krb5int_algorithm_id *kalg_ids;

	    for(alg_ids=localAuthPack.supportedCMSTypes;
	        *alg_ids;
		alg_ids++) {
		num_types++;
	    }
	    *cms_types = kalg_ids = (krb5int_algorithm_id *)calloc(num_types,
		sizeof(krb5int_algorithm_id));
	    *num_cms_types = num_types;
	    alg_ids = localAuthPack.supportedCMSTypes;
	    for(dex=0; dex<num_types; dex++) {
		if(alg_ids[dex]->algorithm.Data) {
		    pkiCssmDataToKrb5Data(&alg_ids[dex]->algorithm,
			&kalg_ids[dex].algorithm);
		}
		if(alg_ids[dex]->parameters.Data) {
		    pkiCssmDataToKrb5Data(&alg_ids[dex]->parameters,
			&kalg_ids[dex].parameters);
		}
	    }
	}
    }
    ourRtn = 0;
errOut:
    SecAsn1CoderRelease(coder);
    return ourRtn;
}
コード例 #11
0
/*
 * Encode AuthPack, public key version (no Diffie-Hellman components).
 */
krb5_error_code krb5int_pkinit_auth_pack_encode(
    krb5_timestamp		kctime,
    krb5_int32			cusec,		    /* microseconds */
    krb5_ui_4			nonce,
    const krb5_checksum		*pa_checksum,
    const krb5int_algorithm_id	*cms_types,	    /* optional */
    krb5_ui_4			num_cms_types,
    krb5_data			*auth_pack) /* mallocd and RETURNED */
{
    KRB5_AuthPack localAuthPack;
    SecAsn1CoderRef coder;
    CSSM_DATA *cksum = &localAuthPack.pkAuth.paChecksum;
    krb5_error_code ourRtn = 0;
    CSSM_DATA ber = {0, NULL};
    OSStatus ortn;
    char *timeStr = NULL;

    if(SecAsn1CoderCreate(&coder)) {
	return ENOMEM;
    }
    memset(&localAuthPack, 0, sizeof(localAuthPack));
    if(pkiKrbTimestampToStr(kctime, &timeStr)) {
	ourRtn = -1;
	goto errOut;
    }
    localAuthPack.pkAuth.kctime.Data = (uint8 *)timeStr;
    localAuthPack.pkAuth.kctime.Length = strlen(timeStr);
    if(pkiIntToData(cusec, &localAuthPack.pkAuth.cusec, coder)) {
	ourRtn = ENOMEM;
	goto errOut;
    }
    if(pkiIntToData(nonce, &localAuthPack.pkAuth.nonce, coder)) {
	ourRtn = ENOMEM;
	goto errOut;
    }
    cksum->Data = (uint8 *)pa_checksum->contents;
    cksum->Length = pa_checksum->length;

    if((cms_types != NULL) && (num_cms_types != 0)) {
	unsigned dex;
	CSSM_X509_ALGORITHM_IDENTIFIER **algIds;

	/* build a NULL_terminated array of CSSM_X509_ALGORITHM_IDENTIFIERs */
	localAuthPack.supportedCMSTypes = (CSSM_X509_ALGORITHM_IDENTIFIER **)
	    SecAsn1Malloc(coder,
		(num_cms_types + 1) * sizeof(CSSM_X509_ALGORITHM_IDENTIFIER *));
	algIds = localAuthPack.supportedCMSTypes;
	for(dex=0; dex<num_cms_types; dex++) {
	    algIds[dex] = (CSSM_X509_ALGORITHM_IDENTIFIER *)
		SecAsn1Malloc(coder, sizeof(CSSM_X509_ALGORITHM_IDENTIFIER));
	    pkiKrb5DataToCssm(&cms_types[dex].algorithm,
		&algIds[dex]->algorithm, coder);
	    if(cms_types[dex].parameters.data != NULL) {
		pkiKrb5DataToCssm(&cms_types[dex].parameters,
		    &algIds[dex]->parameters, coder);
	    }
	    else {
		algIds[dex]->parameters.Data = NULL;
		algIds[dex]->parameters.Length = 0;
	    }
	}
	algIds[num_cms_types] = NULL;
    }
    ortn = SecAsn1EncodeItem(coder, &localAuthPack, KRB5_AuthPackTemplate, &ber);
    if(ortn) {
	ourRtn = ENOMEM;
	goto errOut;
    }

    if(pkiCssmDataToKrb5Data(&ber, auth_pack)) {
	ourRtn = ENOMEM;
    }
    else {
	auth_pack->magic = KV5M_AUTHENTICATOR;
	ourRtn = 0;
    }
errOut:
    SecAsn1CoderRelease(coder);
    return ourRtn;
}