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