c - How can I duplicate an EVP_PKEY struct without knowing the underlying algorithm? -
i'm working on tls implementation (using openssl 1.0.1s) employs 1024-bit rsa keys both encryption , authentication. want upgrade ec performance reasons, need remain backward compatible.
so decided use openssl's evp api have common code possible. but, i've run problem when want read certificates ram (stored in asn.1 der format), can't find way copy evp_pkey
struct (no pkey_dup
or pkey_copy
or of sort).
i want avoid switch-casing evp_pkey.type
next upgrade smoother, suggestions?
i managed duplicate converting der , back. general i2d/d2i functions call specific ones.
code:
error_code_enum read_evp_pkey_from_ram (int index, int db_id, evp_pkey **pkey_ptr_ptr){ evp_pkey *pkey; unsigned char *p; unsigned char *der_ptr; int der_size; int pub_len, priv_len, type; *pkey_ptr_ptr = null; if ((pkey = sensitive_evp_pkey_data[db_id][index]) == null) return error_code_no_key; type = pkey->type; /*passing null char *out returns length only*/ pub_len = i2d_pubkey(pkey, null); priv_len = i2d_privatekey(pkey, null); if (pub_len <= 0 || priv_len <= 0 ) return error_code_general_error; der_size = pub_len + priv_len + 2 * sizeof(uint_16); if ((der_ptr = openssl_malloc(der_size)) == null) return error_code_no_memory; /* * store key in buffer as: * |public key length | public key | private key length | private key| */ p = der_ptr; *(uint_16*)p = pub_len; p += 2; pub_len = i2d_pubkey(pkey,&p);/*p incremented here key size*/ *(uint_16*)p = priv_len; p += 2; priv_len = i2d_privatekey(pkey,&p); p = der_ptr + 2; /*pass null evp_pkey *key causes fresh evp_pkey struct allocated , pointer returned*/ pkey = d2i_pubkey(null, (const unsigned char **)&p, pub_len); if (pkey == null){ openssl_free(der_ptr); return error_code_general_error; } priv_len = *(uint_16 *)p; if (priv_len == 0){ evp_pkey_free(pkey); openssl_free(der_ptr); return error_code_general_error; } p += 2; /*now pass &pkey*/ if (d2i_privatekey(type, &pkey, (const unsigned char **)&p, priv_len) == null){ openssl_free(der_ptr); return error_code_general_error; } openssl_free(der_ptr); *pkey_ptr_ptr = pkey; return error_code_no_error;
note i2d/d2i functions increment pointers given
Comments
Post a Comment