OCSPExtensions::OCSPExtensions( NSS_CertExtension **nssExts) : mCoder(NULL), mNumExtensions(0), mExtensions(NULL) { SecAsn1CoderCreate(&mCoder); mNumExtensions = ocspdArraySize((const void **)nssExts); if(mNumExtensions == 0) { return; } mExtensions = (OCSPExtension **)SecAsn1Malloc(mCoder, (mNumExtensions * sizeof(OCSPExtension *))); for(unsigned dex=0; dex<mNumExtensions; dex++) { try { mExtensions[dex] = OCSPExtension::createFromNSS(mCoder, *nssExts[dex]); if(mExtensions[dex] == NULL) { ocspdErrorLog("OCSPExtensions: extension failure (NULL) dex %u\n", dex); CssmError::throwMe(CSSMERR_APPLETP_OCSP_BAD_RESPONSE); } if(mExtensions[dex]->unrecognizedCritical()) { ocspdErrorLog("OCSPExtensions: unrecognized critical extension\n"); CssmError::throwMe(CSSMERR_APPLETP_OCSP_BAD_RESPONSE); } } catch (...) { ocspdErrorLog("OCSPExtensions: extension failure dex %u\n", dex); CssmError::throwMe(CSSMERR_APPLETP_OCSP_BAD_RESPONSE); } } }
/* * Constructor during encode, called from subclass-specific constructorÊ(which * always has all of the subclass-specific arguments). */ OCSPExtension::OCSPExtension( SecAsn1CoderRef coder, // passed to subclass constructor const CSSM_OID &extnId, // subclass knows this OCSPExtensionTag tag, // subclass knows this bool critical) // passed to subclass constructor : mNssExt(NULL), // we'll cook this up mCoder(coder), mCritical(critical), mTag(tag), mUnrecognizedCritical(false) // this is a tautology { mNssExt = (NSS_CertExtension *)SecAsn1Malloc(coder, sizeof(NSS_CertExtension)); memset(mNssExt, 0, sizeof(NSS_CertExtension)); SecAsn1AllocCopyItem(coder, &extnId, &mNssExt->extnId); /* alloc one byte for critical flag */ SecAsn1AllocItem(coder, &mNssExt->critical, 1); mNssExt->critical.Data[0] = critical ? 0xff : 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; }
/* * 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; }