cmssiginfo.c

来自「支持SSL v2/v3, TLS, PKCS #5, PKCS #7, PKCS」· C语言 代码 · 共 872 行 · 第 1/2 页

C
872
字号
SECOidTagNSS_CMSSignerInfo_GetDigestAlgTag(NSSCMSSignerInfo *signerinfo){    SECOidData *algdata;    algdata = SECOID_FindOID (&(signerinfo->digestAlg.algorithm));    if (algdata != NULL)	return algdata->offset;    else	return SEC_OID_UNKNOWN;}CERTCertificateList *NSS_CMSSignerInfo_GetCertList(NSSCMSSignerInfo *signerinfo){    return signerinfo->certList;}intNSS_CMSSignerInfo_GetVersion(NSSCMSSignerInfo *signerinfo){    unsigned long version;    /* always take apart the SECItem */    if (SEC_ASN1DecodeInteger(&(signerinfo->version), &version) != SECSuccess)	return 0;    else	return (int)version;}/* * NSS_CMSSignerInfo_GetSigningTime - return the signing time, *				      in UTCTime format, of a CMS signerInfo. * * sinfo - signerInfo data for this signer * * Returns a pointer to XXXX (what?) * A return value of NULL is an error. */SECStatusNSS_CMSSignerInfo_GetSigningTime(NSSCMSSignerInfo *sinfo, PRTime *stime){    NSSCMSAttribute *attr;    SECItem *value;    if (sinfo == NULL)	return SECFailure;    if (sinfo->signingTime != 0) {	*stime = sinfo->signingTime;	/* cached copy */	return SECSuccess;    }    attr = NSS_CMSAttributeArray_FindAttrByOidTag(sinfo->authAttr, SEC_OID_PKCS9_SIGNING_TIME, PR_TRUE);    /* XXXX multi-valued attributes NIH */    if (attr == NULL || (value = NSS_CMSAttribute_GetValue(attr)) == NULL)	return SECFailure;    if (DER_UTCTimeToTime(stime, value) != SECSuccess)	return SECFailure;    sinfo->signingTime = *stime;	/* make cached copy */    return SECSuccess;}/* * Return the signing cert of a CMS signerInfo. * * the certs in the enclosing SignedData must have been imported already */CERTCertificate *NSS_CMSSignerInfo_GetSigningCertificate(NSSCMSSignerInfo *signerinfo, CERTCertDBHandle *certdb){    CERTCertificate *cert;    if (signerinfo->cert != NULL)	return signerinfo->cert;    /* no certdb, and cert hasn't been set yet? */    if (certdb == NULL)	return NULL;    /*     * This cert will also need to be freed, but since we save it     * in signerinfo for later, we do not want to destroy it when     * we leave this function -- we let the clean-up of the entire     * cinfo structure later do the destroy of this cert.     */    switch (signerinfo->signerIdentifier.identifierType) {    case NSSCMSSignerID_IssuerSN:	cert = CERT_FindCertByIssuerAndSN(certdb, signerinfo->signerIdentifier.id.issuerAndSN);	break;    case NSSCMSSignerID_SubjectKeyID:#if 0 /* not yet implemented */	cert = CERT_FindCertBySubjectKeyID(certdb, signerinfo->signerIdentifier.id.subjectKeyID);#else	cert = NULL;#endif	break;    default:	cert = NULL;	break;    }    /* cert can be NULL at that point */    signerinfo->cert = cert;	/* earmark it */    return cert;}/* * NSS_CMSSignerInfo_GetSignerCommonName - return the common name of the signer * * sinfo - signerInfo data for this signer * * Returns a pointer to allocated memory, which must be freed. * A return value of NULL is an error. */char *NSS_CMSSignerInfo_GetSignerCommonName(NSSCMSSignerInfo *sinfo){    CERTCertificate *signercert;    /* will fail if cert is not verified */    if ((signercert = NSS_CMSSignerInfo_GetSigningCertificate(sinfo, NULL)) == NULL)	return NULL;    return (CERT_GetCommonName(&signercert->subject));}/* * NSS_CMSSignerInfo_GetSignerEmailAddress - return the common name of the signer * * sinfo - signerInfo data for this signer * * Returns a pointer to allocated memory, which must be freed. * A return value of NULL is an error. */char *NSS_CMSSignerInfo_GetSignerEmailAddress(NSSCMSSignerInfo *sinfo){    CERTCertificate *signercert;    if ((signercert = NSS_CMSSignerInfo_GetSigningCertificate(sinfo, NULL)) == NULL)	return NULL;    if (signercert->emailAddr == NULL)	return NULL;    return (PORT_Strdup(signercert->emailAddr));}/* * NSS_CMSSignerInfo_AddAuthAttr - add an attribute to the * authenticated (i.e. signed) attributes of "signerinfo".  */SECStatusNSS_CMSSignerInfo_AddAuthAttr(NSSCMSSignerInfo *signerinfo, NSSCMSAttribute *attr){    return NSS_CMSAttributeArray_AddAttr(signerinfo->cmsg->poolp, &(signerinfo->authAttr), attr);}/* * NSS_CMSSignerInfo_AddUnauthAttr - add an attribute to the * unauthenticated attributes of "signerinfo".  */SECStatusNSS_CMSSignerInfo_AddUnauthAttr(NSSCMSSignerInfo *signerinfo, NSSCMSAttribute *attr){    return NSS_CMSAttributeArray_AddAttr(signerinfo->cmsg->poolp, &(signerinfo->unAuthAttr), attr);}/*  * NSS_CMSSignerInfo_AddSigningTime - add the signing time to the * authenticated (i.e. signed) attributes of "signerinfo".  * * This is expected to be included in outgoing signed * messages for email (S/MIME) but is likely useful in other situations. * * This should only be added once; a second call will do nothing. * * XXX This will probably just shove the current time into "signerinfo" * but it will not actually get signed until the entire item is * processed for encoding.  Is this (expected to be small) delay okay? */SECStatusNSS_CMSSignerInfo_AddSigningTime(NSSCMSSignerInfo *signerinfo, PRTime t){    NSSCMSAttribute *attr;    SECItem stime;    void *mark;    PLArenaPool *poolp;    poolp = signerinfo->cmsg->poolp;    mark = PORT_ArenaMark(poolp);    /* create new signing time attribute */    if (DER_TimeToUTCTime(&stime, t) != SECSuccess)	goto loser;    if ((attr = NSS_CMSAttribute_Create(poolp, SEC_OID_PKCS9_SIGNING_TIME, &stime, PR_FALSE)) == NULL) {	SECITEM_FreeItem (&stime, PR_FALSE);	goto loser;    }    SECITEM_FreeItem (&stime, PR_FALSE);    if (NSS_CMSSignerInfo_AddAuthAttr(signerinfo, attr) != SECSuccess)	goto loser;    PORT_ArenaUnmark (poolp, mark);    return SECSuccess;loser:    PORT_ArenaRelease (poolp, mark);    return SECFailure;}/*  * NSS_CMSSignerInfo_AddSMIMECaps - add a SMIMECapabilities attribute to the * authenticated (i.e. signed) attributes of "signerinfo".  * * This is expected to be included in outgoing signed * messages for email (S/MIME). */SECStatusNSS_CMSSignerInfo_AddSMIMECaps(NSSCMSSignerInfo *signerinfo){    NSSCMSAttribute *attr;    SECItem *smimecaps = NULL;    void *mark;    PLArenaPool *poolp;    poolp = signerinfo->cmsg->poolp;    mark = PORT_ArenaMark(poolp);    smimecaps = SECITEM_AllocItem(poolp, NULL, 0);    if (smimecaps == NULL)	goto loser;    /* create new signing time attribute */    if (NSS_SMIMEUtil_CreateSMIMECapabilities(poolp, smimecaps,			    PK11_FortezzaHasKEA(signerinfo->cert)) != SECSuccess)	goto loser;    if ((attr = NSS_CMSAttribute_Create(poolp, SEC_OID_PKCS9_SMIME_CAPABILITIES, smimecaps, PR_TRUE)) == NULL)	goto loser;    if (NSS_CMSSignerInfo_AddAuthAttr(signerinfo, attr) != SECSuccess)	goto loser;    PORT_ArenaUnmark (poolp, mark);    return SECSuccess;loser:    PORT_ArenaRelease (poolp, mark);    return SECFailure;}/*  * NSS_CMSSignerInfo_AddSMIMEEncKeyPrefs - add a SMIMEEncryptionKeyPreferences attribute to the * authenticated (i.e. signed) attributes of "signerinfo".  * * This is expected to be included in outgoing signed messages for email (S/MIME). */SECStatusNSS_CMSSignerInfo_AddSMIMEEncKeyPrefs(NSSCMSSignerInfo *signerinfo, CERTCertificate *cert, CERTCertDBHandle *certdb){    NSSCMSAttribute *attr;    SECItem *smimeekp = NULL;    void *mark;    PLArenaPool *poolp;    /* verify this cert for encryption */    if (CERT_VerifyCert(certdb, cert, PR_TRUE, certUsageEmailRecipient, PR_Now(), signerinfo->cmsg->pwfn_arg, NULL) != SECSuccess) {	return SECFailure;    }    poolp = signerinfo->cmsg->poolp;    mark = PORT_ArenaMark(poolp);    smimeekp = SECITEM_AllocItem(poolp, NULL, 0);    if (smimeekp == NULL)	goto loser;    /* create new signing time attribute */    if (NSS_SMIMEUtil_CreateSMIMEEncKeyPrefs(poolp, smimeekp, cert) != SECSuccess)	goto loser;    if ((attr = NSS_CMSAttribute_Create(poolp, SEC_OID_SMIME_ENCRYPTION_KEY_PREFERENCE, smimeekp, PR_TRUE)) == NULL)	goto loser;    if (NSS_CMSSignerInfo_AddAuthAttr(signerinfo, attr) != SECSuccess)	goto loser;    PORT_ArenaUnmark (poolp, mark);    return SECSuccess;loser:    PORT_ArenaRelease (poolp, mark);    return SECFailure;}/*  * NSS_CMSSignerInfo_AddCounterSignature - countersign a signerinfo * * 1. digest the DER-encoded signature value of the original signerinfo * 2. create new signerinfo with correct version, sid, digestAlg * 3. add message-digest authAttr, but NO content-type * 4. sign the authAttrs * 5. DER-encode the new signerInfo * 6. add the whole thing to original signerInfo's unAuthAttrs *    as a SEC_OID_PKCS9_COUNTER_SIGNATURE attribute * * XXXX give back the new signerinfo? */SECStatusNSS_CMSSignerInfo_AddCounterSignature(NSSCMSSignerInfo *signerinfo,				    SECOidTag digestalg, CERTCertificate signingcert){    /* XXXX TBD XXXX */    return SECFailure;}/* * XXXX the following needs to be done in the S/MIME layer code * after signature of a signerinfo is verified */SECStatusNSS_SMIMESignerInfo_SaveSMIMEProfile(NSSCMSSignerInfo *signerinfo){    CERTCertificate *cert = NULL;    SECItem *profile = NULL;    NSSCMSAttribute *attr;    SECItem *utc_stime = NULL;    SECItem *ekp;    CERTCertDBHandle *certdb;    int save_error;    SECStatus rv;    certdb = CERT_GetDefaultCertDB();    /* sanity check - see if verification status is ok (unverified does not count...) */    if (signerinfo->verificationStatus != NSSCMSVS_GoodSignature)	return SECFailure;    /* find preferred encryption cert */    if (!NSS_CMSArray_IsEmpty((void **)signerinfo->authAttr) &&	(attr = NSS_CMSAttributeArray_FindAttrByOidTag(signerinfo->authAttr,			       SEC_OID_SMIME_ENCRYPTION_KEY_PREFERENCE, PR_TRUE)) != NULL)    { /* we have a SMIME_ENCRYPTION_KEY_PREFERENCE attribute! */	ekp = NSS_CMSAttribute_GetValue(attr);	if (ekp == NULL)	    return SECFailure;	/* we assume that all certs coming with the message have been imported to the */	/* temporary database */	cert = NSS_SMIMEUtil_GetCertFromEncryptionKeyPreference(certdb, ekp);	if (cert == NULL)	    return SECFailure;    }    if (cert == NULL) {	/* no preferred cert found?	 * find the cert the signerinfo is signed with instead */	cert = NSS_CMSSignerInfo_GetSigningCertificate(signerinfo, certdb);	if (cert == NULL || cert->emailAddr == NULL)	    return SECFailure;    }    /* verify this cert for encryption (has been verified for signing so far) */    if (CERT_VerifyCert(certdb, cert, PR_TRUE, certUsageEmailRecipient, PR_Now(), signerinfo->cmsg->pwfn_arg, NULL) != SECSuccess) {	return SECFailure;    }    /* XXX store encryption cert permanently? */    /*     * Remember the current error set because we do not care about     * anything set by the functions we are about to call.     */    save_error = PORT_GetError();    if (!NSS_CMSArray_IsEmpty((void **)signerinfo->authAttr)) {	attr = NSS_CMSAttributeArray_FindAttrByOidTag(signerinfo->authAttr,				       SEC_OID_PKCS9_SMIME_CAPABILITIES,				       PR_TRUE);	profile = NSS_CMSAttribute_GetValue(attr);	attr = NSS_CMSAttributeArray_FindAttrByOidTag(signerinfo->authAttr,				       SEC_OID_PKCS9_SIGNING_TIME,				       PR_TRUE);	utc_stime = NSS_CMSAttribute_GetValue(attr);    }    rv = CERT_SaveSMimeProfile (cert, profile, utc_stime);    /*     * Restore the saved error in case the calls above set a new     * one that we do not actually care about.     */    PORT_SetError (save_error);    return rv;}/* * NSS_CMSSignerInfo_IncludeCerts - set cert chain inclusion mode for this signer */SECStatusNSS_CMSSignerInfo_IncludeCerts(NSSCMSSignerInfo *signerinfo, NSSCMSCertChainMode cm, SECCertUsage usage){    if (signerinfo->cert == NULL)	return SECFailure;    switch (cm) {    case NSSCMSCM_None:	signerinfo->certList = NULL;	break;    case NSSCMSCM_CertOnly:	signerinfo->certList = CERT_CertListFromCert(signerinfo->cert);	break;    case NSSCMSCM_CertChain:	signerinfo->certList = CERT_CertChainFromCert(signerinfo->cert, usage, PR_FALSE);	break;    case NSSCMSCM_CertChainWithRoot:	signerinfo->certList = CERT_CertChainFromCert(signerinfo->cert, usage, PR_TRUE);	break;    }    if (cm != NSSCMSCM_None && signerinfo->certList == NULL)	return SECFailure;        return SECSuccess;}

⌨️ 快捷键说明

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