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