cmspubkey.c
来自「支持SSL v2/v3, TLS, PKCS #5, PKCS #7, PKCS」· C语言 代码 · 共 532 行 · 第 1/2 页
C
532 行
loser: if (arena) PORT_FreeArena(arena, PR_FALSE); if (publickey) SECKEY_DestroyPublicKey(publickey); if (ourPrivKey) SECKEY_DestroyPrivateKey(ourPrivKey); return rv;}PK11SymKey *NSS_CMSUtil_DecryptSymKey_MISSI(SECKEYPrivateKey *privkey, SECItem *encKey, SECAlgorithmID *keyEncAlg, SECOidTag bulkalgtag, void *pwfn_arg){ /* fortezza: do a key exchange */ SECStatus err; CK_MECHANISM_TYPE bulkType; PK11SymKey *tek; SECKEYPublicKey *originatorPubKey; NSSCMSSMIMEKEAParameters keaParams; PK11SymKey *bulkkey; int bulkLength; (void) memset(&keaParams, 0, sizeof(keaParams)); /* NOTE: this uses the SMIME v2 recipientinfo for compatibility. All additional KEA parameters are DER-encoded in the encryption algorithm parameters */ /* Decode the KEA algorithm parameters. */ err = SEC_ASN1DecodeItem(NULL, &keaParams, NSS_SMIMEKEAParamTemplateAllParams, &(keyEncAlg->parameters)); if (err != SECSuccess) goto loser; /* get originator's public key */ originatorPubKey = PK11_MakeKEAPubKey(keaParams.originatorKEAKey.data, keaParams.originatorKEAKey.len); if (originatorPubKey == NULL) goto loser; /* Generate the TEK (token exchange key) which we use to unwrap the bulk encryption key. The Derive function generates a shared secret and combines it with the originatorRA data to come up with an unique session key */ tek = PK11_PubDerive(privkey, originatorPubKey, PR_FALSE, &keaParams.originatorRA, NULL, CKM_KEA_KEY_DERIVE, CKM_SKIPJACK_WRAP, CKA_WRAP, 0, pwfn_arg); SECKEY_DestroyPublicKey(originatorPubKey); /* not needed anymore */ if (tek == NULL) goto loser; /* Now that we have the TEK, unwrap the bulk key with which to decrypt the message. We have to do one of two different things depending on whether Skipjack was used for *bulk* encryption of the message. */ bulkType = PK11_AlgtagToMechanism(bulkalgtag); switch (bulkType) { case CKM_SKIPJACK_CBC64: case CKM_SKIPJACK_ECB64: case CKM_SKIPJACK_OFB64: case CKM_SKIPJACK_CFB64: case CKM_SKIPJACK_CFB32: case CKM_SKIPJACK_CFB16: case CKM_SKIPJACK_CFB8: /* Skipjack is being used as the bulk encryption algorithm.*/ /* Unwrap the bulk key. */ bulkkey = PK11_UnwrapSymKey(tek, CKM_SKIPJACK_WRAP, NULL, encKey, CKM_SKIPJACK_CBC64, CKA_DECRYPT, 0); break; default: /* Skipjack was not used for bulk encryption of this message. Use Skipjack CBC64, with the nonSkipjackIV part of the KEA key parameters, to decrypt the bulk key. If the optional parameter bulkKeySize is present, bulk key size is different than the encrypted key size */ if (keaParams.bulkKeySize.len > 0) { err = SEC_ASN1DecodeItem(NULL, &bulkLength, SEC_IntegerTemplate, &keaParams.bulkKeySize); if (err != SECSuccess) goto loser; } bulkkey = PK11_UnwrapSymKey(tek, CKM_SKIPJACK_CBC64, &keaParams.nonSkipjackIV, encKey, bulkType, CKA_DECRYPT, bulkLength); break; } return bulkkey;loser: return NULL;}/* ====== ESDH (Ephemeral-Static Diffie-Hellman) ==================================== */SECStatusNSS_CMSUtil_EncryptSymKey_ESDH(PLArenaPool *poolp, CERTCertificate *cert, PK11SymKey *key, SECItem *encKey, SECItem **ukm, SECAlgorithmID *keyEncAlg, SECItem *pubKey){#if 0 /* not yet done */ SECOidTag certalgtag; /* the certificate's encryption algorithm */ SECOidTag encalgtag; /* the algorithm used for key exchange/agreement */ SECStatus rv; SECItem *params = NULL; int data_len; SECStatus err; PK11SymKey *tek; CERTCertificate *ourCert; SECKEYPublicKey *ourPubKey; NSSCMSKEATemplateSelector whichKEA; certalgtag = SECOID_GetAlgorithmTag(&(cert->subjectPublicKeyInfo.algorithm)); PORT_Assert(certalgtag == SEC_OID_X942_DIFFIE_HELMAN_KEY); /* We really want to show our KEA tag as the key exchange algorithm tag. */ encalgtag = SEC_OID_CMS_EPHEMERAL_STATIC_DIFFIE_HELLMAN; /* Get the public key of the recipient. */ publickey = CERT_ExtractPublicKey(cert); if (publickey == NULL) goto loser; /* XXXX generate a DH key pair on a PKCS11 module (XXX which parameters?) */ /* XXXX */ourCert = PK11_FindBestKEAMatch(cert, wincx); if (ourCert == NULL) goto loser; arena = PORT_NewArena(1024); if (arena == NULL) goto loser; /* While we're here, extract the key pair's public key data and copy it into */ /* the outgoing parameters. */ /* XXXX */ourPubKey = CERT_ExtractPublicKey(ourCert); if (ourPubKey == NULL) { goto loser; } SECITEM_CopyItem(arena, pubKey, /* XXX */&(ourPubKey->u.fortezza.KEAKey)); SECKEY_DestroyPublicKey(ourPubKey); /* we only need the private key from now on */ ourPubKey = NULL; /* Extract our private key in order to derive the KEA key. */ ourPrivKey = PK11_FindKeyByAnyCert(ourCert,wincx); CERT_DestroyCertificate(ourCert); /* we're done with this */ if (!ourPrivKey) goto loser; /* If ukm desired, prepare it - allocate enough space (filled with zeros). */ if (ukm) { ukm->data = (unsigned char*)PORT_ArenaZAlloc(arena,/* XXXX */); ukm->len = /* XXXX */; } /* Generate the KEK (key exchange key) according to RFC2631 which we use * to wrap the bulk encryption key. */ kek = PK11_PubDerive(ourPrivKey, publickey, PR_TRUE, ukm, NULL, /* XXXX */CKM_KEA_KEY_DERIVE, /* XXXX */CKM_SKIPJACK_WRAP, CKA_WRAP, 0, wincx); SECKEY_DestroyPublicKey(publickey); SECKEY_DestroyPrivateKey(ourPrivKey); publickey = NULL; ourPrivKey = NULL; if (!kek) goto loser; /* allocate space for the encrypted CEK (bulk key) */ encKey->data = (unsigned char*)PORT_ArenaAlloc(poolp, SMIME_FORTEZZA_MAX_KEY_SIZE); encKey->len = SMIME_FORTEZZA_MAX_KEY_SIZE; if (encKey->data == NULL) { PK11_FreeSymKey(kek); goto loser; } /* Wrap the bulk key using CMSRC2WRAP or CMS3DESWRAP, depending on the */ /* bulk encryption algorithm */ switch (/* XXXX */PK11_AlgtagToMechanism(enccinfo->encalg)) { case /* XXXX */CKM_SKIPJACK_CFB8: err = PK11_WrapSymKey(/* XXXX */CKM_CMS3DES_WRAP, NULL, kek, bulkkey, encKey); whichKEA = NSSCMSKEAUsesSkipjack; break; case /* XXXX */CKM_SKIPJACK_CFB8: err = PK11_WrapSymKey(/* XXXX */CKM_CMSRC2_WRAP, NULL, kek, bulkkey, encKey); whichKEA = NSSCMSKEAUsesSkipjack; break; default: /* XXXX what do we do here? Neither RC2 nor 3DES... */ break; } PK11_FreeSymKey(kek); /* we do not need the KEK anymore */ if (err != SECSuccess) goto loser; /* see RFC2630 12.3.1.1 "keyEncryptionAlgorithm must be ..." */ /* params is the DER encoded key wrap algorithm (with parameters!) (XXX) */ params = SEC_ASN1EncodeItem(arena, NULL, &keaParams, sec_pkcs7_get_kea_template(whichKEA)); if (params == NULL) goto loser; /* now set keyEncAlg */ rv = SECOID_SetAlgorithmID(poolp, keyEncAlg, SEC_OID_CMS_EPHEMERAL_STATIC_DIFFIE_HELLMAN, params); if (rv != SECSuccess) goto loser; /* XXXXXXX this is not right yet */loser: if (arena) { PORT_FreeArena(arena, PR_FALSE); } if (publickey) { SECKEY_DestroyPublicKey(publickey); } if (ourPrivKey) { SECKEY_DestroyPrivateKey(ourPrivKey); }#endif return SECFailure;}PK11SymKey *NSS_CMSUtil_DecryptSymKey_ESDH(SECKEYPrivateKey *privkey, SECItem *encKey, SECAlgorithmID *keyEncAlg, SECOidTag bulkalgtag, void *pwfn_arg){#if 0 /* not yet done */ SECStatus err; CK_MECHANISM_TYPE bulkType; PK11SymKey *tek; SECKEYPublicKey *originatorPubKey; NSSCMSSMIMEKEAParameters keaParams; /* XXXX get originator's public key */ originatorPubKey = PK11_MakeKEAPubKey(keaParams.originatorKEAKey.data, keaParams.originatorKEAKey.len); if (originatorPubKey == NULL) goto loser; /* Generate the TEK (token exchange key) which we use to unwrap the bulk encryption key. The Derive function generates a shared secret and combines it with the originatorRA data to come up with an unique session key */ tek = PK11_PubDerive(privkey, originatorPubKey, PR_FALSE, &keaParams.originatorRA, NULL, CKM_KEA_KEY_DERIVE, CKM_SKIPJACK_WRAP, CKA_WRAP, 0, pwfn_arg); SECKEY_DestroyPublicKey(originatorPubKey); /* not needed anymore */ if (tek == NULL) goto loser; /* Now that we have the TEK, unwrap the bulk key with which to decrypt the message. */ /* Skipjack is being used as the bulk encryption algorithm.*/ /* Unwrap the bulk key. */ bulkkey = PK11_UnwrapSymKey(tek, CKM_SKIPJACK_WRAP, NULL, encKey, CKM_SKIPJACK_CBC64, CKA_DECRYPT, 0); return bulkkey;loser:#endif return NULL;}
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?