crmfcont.c
来自「支持SSL v2/v3, TLS, PKCS #5, PKCS #7, PKCS」· C语言 代码 · 共 1,165 行 · 第 1/3 页
C
1,165 行
retOptions = crmf_create_encr_pivkey_option((CRMFEncryptedKey*)data); break; case crmfKeyGenParameters: retOptions = crmf_create_keygen_param_option((SECItem*)data); break; case crmfArchiveRemGenPrivKey: retOptions = crmf_create_arch_rem_gen_privkey(*(PRBool*)data); break; default: retOptions = NULL; } return retOptions;}static SECStatuscrmf_destroy_encrypted_key(CRMFEncryptedKey *inEncrKey, PRBool freeit){ PORT_Assert(inEncrKey != NULL); if (inEncrKey != NULL) { switch (inEncrKey->encKeyChoice){ case crmfEncryptedValueChoice: crmf_destroy_encrypted_value(&inEncrKey->value.encryptedValue, PR_FALSE); break; case crmfEnvelopedDataChoice: SEC_PKCS7DestroyContentInfo(inEncrKey->value.envelopedData); break; default: break; } if (freeit) { PORT_Free(inEncrKey); } } return SECSuccess;}SECStatus crmf_destroy_pkiarchiveoptions(CRMFPKIArchiveOptions *inArchOptions, PRBool freeit){ PORT_Assert(inArchOptions != NULL); if (inArchOptions != NULL) { switch (inArchOptions->archOption) { case crmfEncryptedPrivateKey: crmf_destroy_encrypted_key(&inArchOptions->option.encryptedKey, PR_FALSE); break; case crmfKeyGenParameters: case crmfArchiveRemGenPrivKey: /* This is a union, so having a pointer to one is like * having a pointer to both. */ SECITEM_FreeItem(&inArchOptions->option.keyGenParameters, PR_FALSE); break; case crmfNoArchiveOptions: break; } if (freeit) { PORT_Free(inArchOptions); } } return SECSuccess;}SECStatusCRMF_DestroyPKIArchiveOptions(CRMFPKIArchiveOptions *inArchOptions) { return crmf_destroy_pkiarchiveoptions(inArchOptions, PR_TRUE);}static CK_MECHANISM_TYPEcrmf_get_non_pad_mechanism(CK_MECHANISM_TYPE type){ switch (type) { case CKM_DES3_CBC_PAD: return CKM_DES3_CBC; case CKM_CAST5_CBC_PAD: return CKM_CAST5_CBC; case CKM_DES_CBC_PAD: return CKM_DES_CBC; case CKM_IDEA_CBC_PAD: return CKM_IDEA_CBC; case CKM_CAST3_CBC_PAD: return CKM_CAST3_CBC; case CKM_CAST_CBC_PAD: return CKM_CAST_CBC; case CKM_RC5_CBC_PAD: return CKM_RC5_CBC; case CKM_RC2_CBC_PAD: return CKM_RC2_CBC; case CKM_CDMF_CBC_PAD: return CKM_CDMF_CBC; } return type;}static CK_MECHANISM_TYPEcrmf_get_pad_mech_from_tag(SECOidTag oidTag){ CK_MECHANISM_TYPE mechType; SECOidData *oidData; oidData = SECOID_FindOIDByTag(oidTag); mechType = (CK_MECHANISM_TYPE)oidData->mechanism; return PK11_GetPadMechanism(mechType);}static CK_MECHANISM_TYPEcrmf_get_best_privkey_wrap_mechanism(PK11SlotInfo *slot) { CK_MECHANISM_TYPE privKeyPadMechs[] = { CKM_DES3_CBC_PAD, CKM_CAST5_CBC_PAD, CKM_DES_CBC_PAD, CKM_IDEA_CBC_PAD, CKM_CAST3_CBC_PAD, CKM_CAST_CBC_PAD, CKM_RC5_CBC_PAD, CKM_RC2_CBC_PAD, CKM_CDMF_CBC_PAD }; int mechCount = sizeof(privKeyPadMechs)/sizeof(privKeyPadMechs[0]); int i; for (i=0; i < mechCount; i++) { if (PK11_DoesMechanism(slot, privKeyPadMechs[i])) { return privKeyPadMechs[i]; } } return CKM_INVALID_MECHANISM;}CK_MECHANISM_TYPECRMF_GetBestWrapPadMechanism(PK11SlotInfo *slot){ return crmf_get_best_privkey_wrap_mechanism(slot);}static SECItem*crmf_get_iv(CK_MECHANISM_TYPE mechType){ int iv_size = PK11_GetIVLength(mechType); SECItem *iv; SECStatus rv; iv = PORT_ZNew(SECItem); if (iv == NULL) { return NULL; } if (iv_size == 0) { iv->data = NULL; iv->len = 0; return iv; } iv->data = PORT_NewArray(unsigned char, iv_size); if (iv->data == NULL) { iv->len = 0; return iv; } iv->len = iv_size; rv = PK11_GenerateRandom(iv->data, iv->len); if (rv != SECSuccess) { PORT_Free(iv->data); iv->data = NULL; iv->len = 0; } return iv;}SECItem*CRMF_GetIVFromMechanism(CK_MECHANISM_TYPE mechType){ return crmf_get_iv(mechType);}CK_MECHANISM_TYPEcrmf_get_mechanism_from_public_key(SECKEYPublicKey *inPubKey){ CERTSubjectPublicKeyInfo *spki = NULL; SECOidTag tag; spki = SECKEY_CreateSubjectPublicKeyInfo(inPubKey); if (spki == NULL) { return CKM_INVALID_MECHANISM; } tag = SECOID_FindOIDTag(&spki->algorithm.algorithm); SECKEY_DestroySubjectPublicKeyInfo(spki); spki = NULL; return PK11_AlgtagToMechanism(tag);}SECItem*crmf_get_public_value(SECKEYPublicKey *pubKey, SECItem *dest){ SECItem *pubValue; if (dest != NULL) { pubValue = dest; } else { pubValue = PORT_ZNew(SECItem); } switch(pubKey->keyType) { case dsaKey: SECITEM_CopyItem(NULL, pubValue, &pubKey->u.dsa.publicValue); break; case rsaKey: SECITEM_CopyItem(NULL, pubValue, &pubKey->u.rsa.modulus); break; case dhKey: SECITEM_CopyItem(NULL, pubValue, &pubKey->u.dh.publicValue); break; default: if (dest == NULL) { PORT_Free(pubValue); } pubValue = NULL; break; } return pubValue;}static SECItem*crmf_decode_params(SECItem *inParams){ SECItem *params; SECStatus rv; params = PORT_ZNew(SECItem); rv = SEC_ASN1DecodeItem(NULL, params, SEC_OctetStringTemplate, inParams); if (rv != SECSuccess) { SECITEM_FreeItem(params, PR_TRUE); return NULL; } return params;}intcrmf_get_key_size_from_mech(CK_MECHANISM_TYPE mechType){ CK_MECHANISM_TYPE keyGen = PK11_GetKeyGen(mechType); switch (keyGen) { case CKM_CDMF_KEY_GEN: case CKM_DES_KEY_GEN: return 8; case CKM_DES2_KEY_GEN: return 16; case CKM_DES3_KEY_GEN: return 24; } return 0;}SECStatuscrmf_encrypted_value_unwrap_priv_key(PRArenaPool *poolp, CRMFEncryptedValue *encValue, SECKEYPrivateKey *privKey, SECKEYPublicKey *newPubKey, SECItem *nickname, PK11SlotInfo *slot, unsigned char keyUsage, SECKEYPrivateKey **unWrappedKey, void *wincx){ PK11SymKey *wrappingKey = NULL; CK_MECHANISM_TYPE wrapMechType; SECOidTag oidTag; SECItem *params = NULL, *publicValue = NULL; int keySize, origLen; CK_KEY_TYPE keyType; CK_ATTRIBUTE_TYPE *usage; CK_ATTRIBUTE_TYPE rsaUsage[] = { CKA_UNWRAP, CKA_DECRYPT, CKA_SIGN, CKA_SIGN_RECOVER }; CK_ATTRIBUTE_TYPE dsaUsage[] = { CKA_SIGN }; CK_ATTRIBUTE_TYPE dhUsage[] = { CKA_DERIVE }; int usageCount; oidTag = SECOID_GetAlgorithmTag(encValue->symmAlg); wrapMechType = crmf_get_pad_mech_from_tag(oidTag); keySize = crmf_get_key_size_from_mech(wrapMechType); wrappingKey = PK11_PubUnwrapSymKey(privKey, &encValue->encSymmKey, wrapMechType, CKA_UNWRAP, keySize); if (wrappingKey == NULL) { goto loser; }/* Make the length a byte length instead of bit length*/ params = (encValue->symmAlg != NULL) ? crmf_decode_params(&encValue->symmAlg->parameters) : NULL; origLen = encValue->encValue.len; encValue->encValue.len = CRMF_BITS_TO_BYTES(origLen); publicValue = crmf_get_public_value(newPubKey, NULL); switch(newPubKey->keyType) { default: case rsaKey: keyType = CKK_RSA; switch (keyUsage & (KU_KEY_ENCIPHERMENT|KU_DIGITAL_SIGNATURE)) { case KU_KEY_ENCIPHERMENT: usage = rsaUsage; usageCount = 2; break; case KU_DIGITAL_SIGNATURE: usage = &rsaUsage[2]; usageCount = 2; break; case KU_KEY_ENCIPHERMENT|KU_DIGITAL_SIGNATURE: case 0: /* default to everything */ usage = rsaUsage; usageCount = 4; break; } break; case dhKey: keyType = CKK_DH; usage = dhUsage; usageCount = sizeof(dhUsage)/sizeof(dhUsage[0]); break; case dsaKey: keyType = CKK_DSA; usage = dsaUsage; usageCount = sizeof(dsaUsage)/sizeof(dsaUsage[0]); break; } *unWrappedKey = PK11_UnwrapPrivKey(slot, wrappingKey, wrapMechType, params, &encValue->encValue, nickname, publicValue, PR_TRUE,PR_TRUE, keyType, usage, usageCount, wincx); encValue->encValue.len = origLen; if (*unWrappedKey == NULL) { goto loser; } SECITEM_FreeItem (publicValue, PR_TRUE); if (params!= NULL) { SECITEM_FreeItem(params, PR_TRUE); } PK11_FreeSymKey(wrappingKey); return SECSuccess; loser: *unWrappedKey = NULL; return SECFailure;}CRMFEncryptedValue *crmf_create_encrypted_value_wrapped_privkey(SECKEYPrivateKey *inPrivKey, SECKEYPublicKey *inCAKey, CRMFEncryptedValue *destValue){ SECItem wrappedPrivKey, wrappedSymKey; SECItem encodedParam, *dummy; SECStatus rv; CK_MECHANISM_TYPE pubMechType, symKeyType; unsigned char *wrappedSymKeyBits; unsigned char *wrappedPrivKeyBits; SECItem *iv = NULL; SECOidTag tag; PK11SymKey *symKey; PK11SlotInfo *slot; SECAlgorithmID *symmAlg; CRMFEncryptedValue *myEncrValue = NULL; encodedParam.data = NULL; wrappedSymKeyBits = PORT_NewArray(unsigned char, MAX_WRAPPED_KEY_LEN); wrappedPrivKeyBits = PORT_NewArray(unsigned char, MAX_WRAPPED_KEY_LEN); if (wrappedSymKeyBits == NULL || wrappedPrivKeyBits == NULL) { goto loser; } if (destValue == NULL) { myEncrValue = destValue = PORT_ZNew(CRMFEncryptedValue); if (destValue == NULL) { goto loser; } } pubMechType = crmf_get_mechanism_from_public_key(inCAKey); if (pubMechType == CKM_INVALID_MECHANISM) { /* XXX I should probably do something here for non-RSA * keys that are in certs. (ie DSA) */ goto loser; } slot = inPrivKey->pkcs11Slot; PORT_Assert(slot != NULL); symKeyType = crmf_get_best_privkey_wrap_mechanism(slot); symKey = PK11_KeyGen(slot, symKeyType, NULL, 0, NULL); if (symKey == NULL) { goto loser; } wrappedSymKey.data = wrappedSymKeyBits;
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?