Пример #1
0
SECStatus
PK11_ImportPrivateKeyInfoAndReturnKey(PK11SlotInfo *slot,
                                      SECKEYPrivateKeyInfo *pki, SECItem *nickname, SECItem *publicValue,
                                      PRBool isPerm, PRBool isPrivate, unsigned int keyUsage,
                                      SECKEYPrivateKey **privk, void *wincx)
{
    SECStatus rv = SECFailure;
    SECKEYRawPrivateKey *lpk = NULL;
    const SEC_ASN1Template *keyTemplate, *paramTemplate;
    void *paramDest = NULL;
    PLArenaPool *arena = NULL;

    arena = PORT_NewArena(2048);
    if (!arena) {
        return SECFailure;
    }

    /* need to change this to use RSA/DSA keys */
    lpk = (SECKEYRawPrivateKey *)PORT_ArenaZAlloc(arena,
                                                  sizeof(SECKEYRawPrivateKey));
    if (lpk == NULL) {
        goto loser;
    }
    lpk->arena = arena;

    switch (SECOID_GetAlgorithmTag(&pki->algorithm)) {
        case SEC_OID_PKCS1_RSA_ENCRYPTION:
            prepare_rsa_priv_key_export_for_asn1(lpk);
            keyTemplate = SECKEY_RSAPrivateKeyExportTemplate;
            paramTemplate = NULL;
            paramDest = NULL;
            lpk->keyType = rsaKey;
            break;
        case SEC_OID_ANSIX9_DSA_SIGNATURE:
            prepare_dsa_priv_key_export_for_asn1(lpk);
            keyTemplate = SECKEY_DSAPrivateKeyExportTemplate;
            paramTemplate = SECKEY_PQGParamsTemplate;
            paramDest = &(lpk->u.dsa.params);
            lpk->keyType = dsaKey;
            break;
        case SEC_OID_X942_DIFFIE_HELMAN_KEY:
            if (!publicValue) {
                goto loser;
            }
            prepare_dh_priv_key_export_for_asn1(lpk);
            keyTemplate = SECKEY_DHPrivateKeyExportTemplate;
            paramTemplate = NULL;
            paramDest = NULL;
            lpk->keyType = dhKey;
            break;
        case SEC_OID_ANSIX962_EC_PUBLIC_KEY:
            prepare_ec_priv_key_export_for_asn1(lpk);
            keyTemplate = SECKEY_ECPrivateKeyExportTemplate;
            paramTemplate = NULL;
            paramDest = NULL;
            lpk->keyType = ecKey;
            break;

        default:
            keyTemplate = NULL;
            paramTemplate = NULL;
            paramDest = NULL;
            break;
    }

    if (!keyTemplate) {
        goto loser;
    }

    /* decode the private key and any algorithm parameters */
    rv = SEC_QuickDERDecodeItem(arena, lpk, keyTemplate, &pki->privateKey);
    if (rv != SECSuccess) {
        goto loser;
    }

    if (lpk->keyType == ecKey) {
        /* Convert length in bits to length in bytes. */
        lpk->u.ec.publicValue.len >>= 3;

        /* Always override curveOID, we're ignoring any given value. */
        rv = SECITEM_CopyItem(arena, &lpk->u.ec.curveOID,
                              &pki->algorithm.parameters);
        if (rv != SECSuccess) {
            goto loser;
        }
    }
Пример #2
0
SECStatus
PK11_ImportPrivateKeyInfoAndReturnKey(PK11SlotInfo *slot,
	SECKEYPrivateKeyInfo *pki, SECItem *nickname, SECItem *publicValue,
	PRBool isPerm, PRBool isPrivate, unsigned int keyUsage,
	SECKEYPrivateKey **privk, void *wincx) 
{
    CK_KEY_TYPE keyType = CKK_RSA;
    SECStatus rv = SECFailure;
    SECKEYRawPrivateKey *lpk = NULL;
    const SEC_ASN1Template *keyTemplate, *paramTemplate;
    void *paramDest = NULL;
    PRArenaPool *arena;

    arena = PORT_NewArena(2048);
    if(!arena) {
	return SECFailure;
    }

    /* need to change this to use RSA/DSA keys */
    lpk = (SECKEYRawPrivateKey *)PORT_ArenaZAlloc(arena,
						  sizeof(SECKEYRawPrivateKey));
    if(lpk == NULL) {
	goto loser;
    }
    lpk->arena = arena;

    switch(SECOID_GetAlgorithmTag(&pki->algorithm)) {
	case SEC_OID_PKCS1_RSA_ENCRYPTION:
	    prepare_rsa_priv_key_export_for_asn1(lpk);
	    keyTemplate = SECKEY_RSAPrivateKeyExportTemplate;
	    paramTemplate = NULL;
	    paramDest = NULL;
	    lpk->keyType = rsaKey;
	    keyType = CKK_RSA;
	    break;
	case SEC_OID_ANSIX9_DSA_SIGNATURE:
	    prepare_dsa_priv_key_export_for_asn1(lpk);
	    keyTemplate = SECKEY_DSAPrivateKeyExportTemplate;
	    paramTemplate = SECKEY_PQGParamsTemplate;
	    paramDest = &(lpk->u.dsa.params);
	    lpk->keyType = dsaKey;
	    keyType = CKK_DSA;
	    break;
	case SEC_OID_X942_DIFFIE_HELMAN_KEY:
	    if(!publicValue) {
		goto loser;
	    }
	    prepare_dh_priv_key_export_for_asn1(lpk);
	    keyTemplate = SECKEY_DHPrivateKeyExportTemplate;
	    paramTemplate = NULL;
	    paramDest = NULL;
	    lpk->keyType = dhKey;
	    keyType = CKK_DH;
	    break;

	default:
	    keyTemplate   = NULL;
	    paramTemplate = NULL;
	    paramDest     = NULL;
	    break;
    }

    if(!keyTemplate) {
	goto loser;
    }

    /* decode the private key and any algorithm parameters */
    rv = SEC_ASN1DecodeItem(arena, lpk, keyTemplate, &pki->privateKey);
    if(rv != SECSuccess) {
	goto loser;
    }
    if(paramDest && paramTemplate) {
	rv = SEC_ASN1DecodeItem(arena, paramDest, paramTemplate, 
				 &(pki->algorithm.parameters));
	if(rv != SECSuccess) {
	    goto loser;
	}
    }

    rv = PK11_ImportAndReturnPrivateKey(slot,lpk,nickname,publicValue, isPerm, 
	isPrivate,  keyUsage, privk, wincx);


loser:
    if (lpk!= NULL) {
	PORT_FreeArena(arena, PR_TRUE);
    }

    return rv;
}
Пример #3
0
/*
 * The caller is responsible for freeing the return value by passing it to
 * SECKEY_DestroyPrivateKeyInfo(..., PR_TRUE).
 */
SECKEYPrivateKeyInfo *
PK11_ExportPrivKeyInfo(SECKEYPrivateKey *pk, void *wincx)
{
    /* PrivateKeyInfo version (always zero) */
    const unsigned char pkiVersion = 0;
    /* RSAPrivateKey version (always zero) */
    const unsigned char rsaVersion = 0;
    PLArenaPool *arena = NULL;
    SECKEYRawPrivateKey rawKey;
    SECKEYPrivateKeyInfo *pki;
    SECItem *encoded;
    SECStatus rv;

    if (pk->keyType != rsaKey) {
        PORT_SetError(PR_NOT_IMPLEMENTED_ERROR);
        goto loser;
    }

    arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE);
    if (!arena) {
        goto loser;
    }
    memset(&rawKey, 0, sizeof(rawKey));
    rawKey.keyType = pk->keyType;
    rawKey.u.rsa.version.type = siUnsignedInteger;
    rawKey.u.rsa.version.data = (unsigned char *)PORT_ArenaAlloc(arena, 1);
    if (!rawKey.u.rsa.version.data) {
        goto loser;
    }
    rawKey.u.rsa.version.data[0] = rsaVersion;
    rawKey.u.rsa.version.len = 1;

    /* Read the component attributes of the private key */
    prepare_rsa_priv_key_export_for_asn1(&rawKey);
    if (!ReadAttribute(pk, CKA_MODULUS, arena, &rawKey.u.rsa.modulus) ||
        !ReadAttribute(pk, CKA_PUBLIC_EXPONENT, arena,
                       &rawKey.u.rsa.publicExponent) ||
        !ReadAttribute(pk, CKA_PRIVATE_EXPONENT, arena,
                       &rawKey.u.rsa.privateExponent) ||
        !ReadAttribute(pk, CKA_PRIME_1, arena, &rawKey.u.rsa.prime1) ||
        !ReadAttribute(pk, CKA_PRIME_2, arena, &rawKey.u.rsa.prime2) ||
        !ReadAttribute(pk, CKA_EXPONENT_1, arena,
                       &rawKey.u.rsa.exponent1) ||
        !ReadAttribute(pk, CKA_EXPONENT_2, arena,
                       &rawKey.u.rsa.exponent2) ||
        !ReadAttribute(pk, CKA_COEFFICIENT, arena,
                       &rawKey.u.rsa.coefficient)) {
        goto loser;
    }

    pki = PORT_ArenaZNew(arena, SECKEYPrivateKeyInfo);
    if (!pki) {
        goto loser;
    }
    encoded = SEC_ASN1EncodeItem(arena, &pki->privateKey, &rawKey,
                                 SECKEY_RSAPrivateKeyExportTemplate);
    if (!encoded) {
        goto loser;
    }
    rv = SECOID_SetAlgorithmID(arena, &pki->algorithm,
                               SEC_OID_PKCS1_RSA_ENCRYPTION, NULL);
    if (rv != SECSuccess) {
        goto loser;
    }
    pki->version.type = siUnsignedInteger;
    pki->version.data = (unsigned char *)PORT_ArenaAlloc(arena, 1);
    if (!pki->version.data) {
        goto loser;
    }
    pki->version.data[0] = pkiVersion;
    pki->version.len = 1;
    pki->arena = arena;

    return pki;

loser:
    if (arena) {
        PORT_FreeArena(arena, PR_TRUE);
    }
    return NULL;
}