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 + -
显示快捷键?