cmsutil.c
来自「支持SSL v2/v3, TLS, PKCS #5, PKCS #7, PKCS」· C语言 代码 · 共 1,277 行 · 第 1/3 页
C
1,277 行
/* we're always passing data in and detaching optionally */ if (NSS_CMSContentInfo_SetContent_Data(cmsg, cinfo, NULL, signOptions.detached) != SECSuccess) { fprintf(stderr, "ERROR: cannot attach CMS data object.\n"); goto loser; } /* * create & attach signer information */ if ((signerinfo = NSS_CMSSignerInfo_Create(cmsg, cert, SEC_OID_SHA1)) == NULL) { fprintf(stderr, "ERROR: cannot create CMS signerInfo object.\n"); goto loser; } /* we want the cert chain included for this one */ if (NSS_CMSSignerInfo_IncludeCerts(signerinfo, NSSCMSCM_CertChain, signOptions.options->certUsage) != SECSuccess) { fprintf(stderr, "ERROR: cannot find cert chain.\n"); goto loser; } if (signOptions.signingTime) { if (NSS_CMSSignerInfo_AddSigningTime(signerinfo, PR_Now()) != SECSuccess) { fprintf(stderr, "ERROR: cannot add signingTime attribute.\n"); goto loser; } } if (signOptions.smimeProfile) { if (NSS_CMSSignerInfo_AddSMIMECaps(signerinfo) != SECSuccess) { fprintf(stderr, "ERROR: cannot add SMIMECaps attribute.\n"); goto loser; } } if (signOptions.encryptionKeyPreferenceNick) { /* get the cert, add it to the message */ if ((ekpcert = CERT_FindCertByNickname(signOptions.options->certHandle, signOptions.encryptionKeyPreferenceNick)) == NULL) { SECU_PrintError(progName, "the corresponding cert for key \"%s\" does not exist", signOptions.encryptionKeyPreferenceNick); goto loser; } if (NSS_CMSSignerInfo_AddSMIMEEncKeyPrefs(signerinfo, ekpcert, signOptions.options->certHandle) != SECSuccess) { fprintf(stderr, "ERROR: cannot add SMIMEEncKeyPrefs attribute.\n"); goto loser; } if (NSS_CMSSignedData_AddCertificate(sigd, ekpcert) != SECSuccess) { fprintf(stderr, "ERROR: cannot add encryption certificate.\n"); goto loser; } } else { /* check signing cert for fitness as encryption cert */ /* if yes, add signing cert as EncryptionKeyPreference */ if (NSS_CMSSignerInfo_AddSMIMEEncKeyPrefs(signerinfo, cert, signOptions.options->certHandle) != SECSuccess) { fprintf(stderr, "ERROR: cannot add default SMIMEEncKeyPrefs attribute.\n"); goto loser; } } if (NSS_CMSSignedData_AddSignerInfo(sigd, signerinfo) != SECSuccess) { fprintf(stderr, "ERROR: cannot add CMS signerInfo object.\n"); goto loser; } return cmsg;loser: NSS_CMSMessage_Destroy(cmsg); return NULL;}static NSSCMSMessage *enveloped_data(struct envelopeOptionsStr envelopeOptions){ NSSCMSMessage *cmsg = NULL; NSSCMSContentInfo *cinfo; NSSCMSEnvelopedData *envd; NSSCMSRecipientInfo *recipientinfo; CERTCertificate **recipientcerts; CERTCertDBHandle *dbhandle; PLArenaPool *tmppoolp = NULL; SECOidTag bulkalgtag; int keysize, i; int cnt; dbhandle = envelopeOptions.options->certHandle; /* count the recipients */ if ((cnt = NSS_CMSArray_Count(envelopeOptions.recipients)) == 0) { fprintf(stderr, "ERROR: please name at least one recipient.\n"); goto loser; } if ((tmppoolp = PORT_NewArena (1024)) == NULL) { fprintf(stderr, "ERROR: out of memory.\n"); goto loser; } /* XXX find the recipient's certs by email address or nickname */ if ((recipientcerts = (CERTCertificate **)PORT_ArenaZAlloc(tmppoolp, (cnt+1)*sizeof(CERTCertificate*))) == NULL) { fprintf(stderr, "ERROR: out of memory.\n"); goto loser; } for (i=0; envelopeOptions.recipients[i] != NULL; i++) { if ((recipientcerts[i] = CERT_FindCertByNicknameOrEmailAddr(dbhandle, envelopeOptions.recipients[i])) == NULL) { SECU_PrintError(progName, "cannot find certificate for \"%s\"", envelopeOptions.recipients[i]); goto loser; } } recipientcerts[i] = NULL; /* find a nice bulk algorithm */ if (NSS_SMIMEUtil_FindBulkAlgForRecipients(recipientcerts, &bulkalgtag, &keysize) != SECSuccess) { fprintf(stderr, "ERROR: cannot find common bulk algorithm.\n"); goto loser; } /* * create the message object */ cmsg = NSS_CMSMessage_Create(NULL); /* create a message on its own pool */ if (cmsg == NULL) { fprintf(stderr, "ERROR: cannot create CMS message.\n"); goto loser; } /* * build chain of objects: message->envelopedData->data */ if ((envd = NSS_CMSEnvelopedData_Create(cmsg, bulkalgtag, keysize)) == NULL) { fprintf(stderr, "ERROR: cannot create CMS envelopedData object.\n"); goto loser; } cinfo = NSS_CMSMessage_GetContentInfo(cmsg); if (NSS_CMSContentInfo_SetContent_EnvelopedData(cmsg, cinfo, envd) != SECSuccess) { fprintf(stderr, "ERROR: cannot attach CMS envelopedData object.\n"); goto loser; } cinfo = NSS_CMSEnvelopedData_GetContentInfo(envd); /* we're always passing data in, so the content is NULL */ if (NSS_CMSContentInfo_SetContent_Data(cmsg, cinfo, NULL, PR_FALSE) != SECSuccess) { fprintf(stderr, "ERROR: cannot attach CMS data object.\n"); goto loser; } /* * create & attach recipient information */ for (i = 0; recipientcerts[i] != NULL; i++) { if ((recipientinfo = NSS_CMSRecipientInfo_Create(cmsg, recipientcerts[i])) == NULL) { fprintf(stderr, "ERROR: cannot create CMS recipientInfo object.\n"); goto loser; } if (NSS_CMSEnvelopedData_AddRecipient(envd, recipientinfo) != SECSuccess) { fprintf(stderr, "ERROR: cannot add CMS recipientInfo object.\n"); goto loser; } } if (tmppoolp) PORT_FreeArena(tmppoolp, PR_FALSE); return cmsg;loser: if (cmsg) NSS_CMSMessage_Destroy(cmsg); if (tmppoolp) PORT_FreeArena(tmppoolp, PR_FALSE); return NULL;}PK11SymKey *dkcb(void *arg, SECAlgorithmID *algid){ return (PK11SymKey*)arg;}static SECStatusget_enc_params(struct encryptOptionsStr *encryptOptions){ struct envelopeOptionsStr envelopeOptions; SECStatus rv = SECFailure; NSSCMSMessage *env_cmsg; NSSCMSContentInfo *cinfo; PK11SymKey *bulkkey = NULL; SECOidTag bulkalgtag; int keysize; int i, nlevels; /* * construct an enveloped data message to obtain bulk keys */ if (encryptOptions->envmsg) { env_cmsg = encryptOptions->envmsg; /* get it from an old message */ } else { SECItem dummyOut = { 0, 0, 0 }; SECItem dummyIn = { 0, 0, 0 }; char str[] = "Hello!"; PLArenaPool *tmparena = PORT_NewArena(1024); dummyIn.data = str; dummyIn.len = strlen(str); envelopeOptions.options = encryptOptions->options; envelopeOptions.recipients = encryptOptions->recipients; env_cmsg = enveloped_data(envelopeOptions); NSS_CMSDEREncode(env_cmsg, &dummyIn, &dummyOut, tmparena); PR_Write(encryptOptions->envFile, dummyOut.data, dummyOut.len); PORT_FreeArena(tmparena, PR_FALSE); } /* * get the content info for the enveloped data */ nlevels = NSS_CMSMessage_ContentLevelCount(env_cmsg); for (i = 0; i < nlevels; i++) { SECOidTag typetag; cinfo = NSS_CMSMessage_ContentLevel(env_cmsg, i); typetag = NSS_CMSContentInfo_GetContentTypeTag(cinfo); if (typetag == SEC_OID_PKCS7_DATA) { /* * get the symmetric key */ bulkalgtag = NSS_CMSContentInfo_GetContentEncAlgTag(cinfo); keysize = NSS_CMSContentInfo_GetBulkKeySize(cinfo); bulkkey = NSS_CMSContentInfo_GetBulkKey(cinfo); break; } } if (i == nlevels) { fprintf(stderr, "%s: could not retrieve enveloped data.", progName); goto loser; } encryptOptions->bulkalgtag = bulkalgtag; encryptOptions->bulkkey = bulkkey; encryptOptions->keysize = keysize; rv = SECSuccess;loser: if (env_cmsg) NSS_CMSMessage_Destroy(env_cmsg); return rv;}static NSSCMSMessage *encrypted_data(struct encryptOptionsStr encryptOptions){ SECStatus rv = SECFailure; NSSCMSMessage *cmsg = NULL; NSSCMSContentInfo *cinfo; NSSCMSEncryptedData *encd; NSSCMSEncoderContext *ecx = NULL; PLArenaPool *tmppoolp = NULL; SECItem derOut = { 0, 0, 0 }; /* arena for output */ tmppoolp = PORT_NewArena(1024); if (!tmppoolp) { fprintf(stderr, "%s: out of memory.\n", progName); return NULL; } /* * create the message object */ cmsg = NSS_CMSMessage_Create(NULL); if (cmsg == NULL) { fprintf(stderr, "ERROR: cannot create CMS message.\n"); goto loser; } /* * build chain of objects: message->encryptedData->data */ if ((encd = NSS_CMSEncryptedData_Create(cmsg, encryptOptions.bulkalgtag, encryptOptions.keysize)) == NULL) { fprintf(stderr, "ERROR: cannot create CMS encryptedData object.\n"); goto loser; } cinfo = NSS_CMSMessage_GetContentInfo(cmsg); if (NSS_CMSContentInfo_SetContent_EncryptedData(cmsg, cinfo, encd) != SECSuccess) { fprintf(stderr, "ERROR: cannot attach CMS encryptedData object.\n"); goto loser; } cinfo = NSS_CMSEncryptedData_GetContentInfo(encd); /* we're always passing data in, so the content is NULL */ if (NSS_CMSContentInfo_SetContent_Data(cmsg, cinfo, NULL, PR_FALSE) != SECSuccess) { fprintf(stderr, "ERROR: cannot attach CMS data object.\n"); goto loser; } ecx = NSS_CMSEncoder_Start(cmsg, NULL, NULL, &derOut, tmppoolp, NULL, NULL, dkcb, encryptOptions.bulkkey, NULL, NULL); if (!ecx) { fprintf(stderr, "%s: cannot create encoder context.\n", progName); goto loser; } rv = NSS_CMSEncoder_Update(ecx, encryptOptions.input->data, encryptOptions.input->len); if (rv) { fprintf(stderr, "%s: failed to add data to encoder.\n", progName); goto loser; } rv = NSS_CMSEncoder_Finish(ecx); if (rv) { fprintf(stderr, "%s: failed to encrypt data.\n", progName); goto loser; } fwrite(derOut.data, derOut.len, 1, encryptOptions.outfile); /* if (bulkkey) PK11_FreeSymKey(bulkkey); */ if (tmppoolp) PORT_FreeArena(tmppoolp, PR_FALSE); return cmsg;loser: /* if (bulkkey) PK11_FreeSymKey(bulkkey); */ if (tmppoolp) PORT_FreeArena(tmppoolp, PR_FALSE); if (cmsg) NSS_CMSMessage_Destroy(cmsg); return NULL;}static NSSCMSMessage *signed_data_certsonly(struct certsonlyOptionsStr certsonlyOptions){ NSSCMSMessage *cmsg = NULL; NSSCMSContentInfo *cinfo; NSSCMSSignedData *sigd; CERTCertificate **certs; CERTCertDBHandle *dbhandle; PLArenaPool *tmppoolp = NULL; int i, cnt; dbhandle = certsonlyOptions.options->certHandle; if ((cnt = NSS_CMSArray_Count(certsonlyOptions.recipients)) == 0) { fprintf(stderr, "ERROR: please indicate the nickname of a certificate to sign with.\n"); goto loser; } if ((tmppoolp = PORT_NewArena (1024)) == NULL) { fprintf(stderr, "ERROR: out of memory.\n"); goto loser; } if ((certs = (CERTCertificate **)PORT_ArenaZAlloc(tmppoolp, (cnt+1)*sizeof(CERTCertificate*))) == NULL) { fprintf(stderr, "ERROR: out of memory.\n"); goto loser; } for (i=0; certsonlyOptions.recipients[i] != NULL; i++) { if ((certs[i] = CERT_FindCertByNicknameOrEmailAddr(dbhandle, certsonlyOptions.recipients[i])) == NULL) { SECU_PrintError(progName, "cannot find certificate for \"%s\"", certsonlyOptions.recipients[i]); goto loser; } } certs[i] = NULL; /* * create the message object */ cmsg = NSS_CMSMessage_Create(NULL); if (cmsg == NULL) { fprintf(stderr, "ERROR: cannot create CMS message.\n"); goto loser; } /* * build chain of objects: message->signedData->data */ if ((sigd = NSS_CMSSignedData_CreateCertsOnly(cmsg, certs[0], PR_TRUE)) == NULL) { fprintf(stderr, "ERROR: cannot create CMS signedData object.\n"); goto loser; } for (i=1; i<cnt; i++) { if (NSS_CMSSignedData_AddCertChain(sigd, certs[i])) { fprintf(stderr, "ERROR: cannot add cert chain for \"%s\".\n", certsonlyOptions.recipients[i]); goto loser; } } cinfo = NSS_CMSMessage_GetContentInfo(cmsg); if (NSS_CMSContentInfo_SetContent_SignedData(cmsg, cinfo, sigd) != SECSuccess) { fprintf(stderr, "ERROR: cannot attach CMS signedData object.\n"); goto loser; } cinfo = NSS_CMSSignedData_GetContentInfo(sigd); if (NSS_CMSContentInfo_SetContent_Data(cmsg, cinfo, NULL, PR_FALSE) != SECSuccess) { fprintf(stderr, "ERROR: cannot attach CMS data object.\n"); goto loser; } if (tmppoolp) PORT_FreeArena(tmppoolp, PR_FALSE); return cmsg;loser: if (cmsg) NSS_CMSMessage_Destroy(cmsg); if (tmppoolp) PORT_FreeArena(tmppoolp, PR_FALSE); return NULL;}typedef enum { UNKNOWN, DECODE, SIGN, ENCRYPT, ENVELOPE, CERTSONLY } Mode;#if 0voidparse_message_for_recipients(PRFileDesc *inFile, struct envelopeOptionsStr *envelopeOptions){ SECItem filedata; SECStatus rv; rv = SECU_FileToItem(&filedata, inFile);}#endif
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?