buffer_t export_key(context& d, key_format fmt) { #if defined(MBEDTLS_PK_WRITE_C) buffer_t output(K::DefaultExportBufferSize, '\0'); if (fmt == pem_format) { mbedcrypto_c_call( mbedtls_pk_write_key_pem, &d.pk_, to_ptr(output), K::DefaultExportBufferSize); output.resize(std::strlen(output.c_str())); finalize_pem(output); } else if (fmt == pk::der_format) { int ret = mbedtls_pk_write_key_der( &d.pk_, to_ptr(output), K::DefaultExportBufferSize); if (ret < 0) throw exception{ret, __FUNCTION__}; size_t length = ret; output.erase(0, K::DefaultExportBufferSize - length); output.resize(length); } return output; #else // MBEDTLS_PK_WRITE_C throw exceptions::pk_export_missed{}; #endif // MBEDTLS_PK_WRITE_C }
int gen_ec_key(uint8_t* buffer, size_t max_length, int (*f_rng) (void *, uint8_t* buf, size_t len), void *p_rng) { mbedtls_pk_context key; memset(&key, 0, sizeof(key)); int error = mbedtls_pk_setup(&key, mbedtls_pk_info_from_type(MBEDTLS_PK_ECKEY)); if (!error) error = mbedtls_ecp_gen_key(MBEDTLS_ECP_DP_SECP256R1, mbedtls_pk_ec(key), f_rng, p_rng ); if (!error) { int result = mbedtls_pk_write_key_der(&key, buffer, max_length); if (result<0) error = result; else if (result>0) { // the key is written to the end of the buffer - align to the start memmove(buffer, buffer+max_length-result, result); } } mbedtls_pk_free(&key); return error; }
static int write_private_key( mbedtls_pk_context *key, const char *output_file ) { int ret; FILE *f; unsigned char output_buf[16000]; unsigned char *c = output_buf; size_t len = 0; memset(output_buf, 0, 16000); #if defined(MBEDTLS_PEM_WRITE_C) if( opt.output_format == OUTPUT_FORMAT_PEM ) { if( ( ret = mbedtls_pk_write_key_pem( key, output_buf, 16000 ) ) != 0 ) return( ret ); len = strlen( (char *) output_buf ); } else #endif { if( ( ret = mbedtls_pk_write_key_der( key, output_buf, 16000 ) ) < 0 ) return( ret ); len = ret; c = output_buf + sizeof(output_buf) - len - 1; } if( ( f = fopen( output_file, "w" ) ) == NULL ) return( -1 ); if( fwrite( c, 1, len, f ) != len ) { fclose( f ); return( -1 ); } fclose( f ); return( 0 ); }
int mbedtls_pk_write_key_pem( mbedtls_pk_context *key, unsigned char *buf, size_t size ) { int ret; unsigned char output_buf[PRV_DER_MAX_BYTES]; const char *begin, *end; size_t olen = 0; if( ( ret = mbedtls_pk_write_key_der( key, output_buf, sizeof(output_buf) ) ) < 0 ) return( ret ); #if defined(MBEDTLS_RSA_C) if( mbedtls_pk_get_type( key ) == MBEDTLS_PK_RSA ) { begin = PEM_BEGIN_PRIVATE_KEY_RSA; end = PEM_END_PRIVATE_KEY_RSA; } else #endif #if defined(MBEDTLS_ECP_C) if( mbedtls_pk_get_type( key ) == MBEDTLS_PK_ECKEY ) { begin = PEM_BEGIN_PRIVATE_KEY_EC; end = PEM_END_PRIVATE_KEY_EC; } else #endif return( MBEDTLS_ERR_PK_FEATURE_UNAVAILABLE ); if( ( ret = mbedtls_pem_write_buffer( begin, end, output_buf + sizeof(output_buf) - ret, ret, buf, size, &olen ) ) != 0 ) { return( ret ); } return( 0 ); }
result_t PKey::exportDer(obj_ptr<Buffer_base> &retVal) { result_t hr; bool priv; hr = isPrivate(priv); if (hr < 0) return hr; int32_t ret; std::string buf; buf.resize(8192); if (priv) ret = mbedtls_pk_write_key_der(&m_key, (unsigned char *)&buf[0], buf.length()); else ret = mbedtls_pk_write_pubkey_der(&m_key, (unsigned char *)&buf[0], buf.length()); if (ret < 0) return CHECK_ERROR(_ssl::setError(ret)); retVal = new Buffer(buf.substr(buf.length() - ret)); return 0; }
/******************************************************************************* * Asymmetric ciphers * *******************************************************************************/ int __attribute__((weak)) wrapped_asym_keygen(Cipher c, CryptoKey key_type, uint8_t* pub, size_t* pub_len, uint8_t* priv, size_t* priv_len) { if (keygen_deferred_handling(key_type)) { // If overriden by user implementation. return _keygen_overrides[key_type](c, key_type, pub, pub_len, priv, priv_len); } int ret = -1; mbedtls_pk_context key; mbedtls_pk_init(&key); uint32_t pers = randomInt(); mbedtls_ctr_drbg_context ctr_drbg; mbedtls_ctr_drbg_init(&ctr_drbg); ret = mbedtls_ctr_drbg_seed( &ctr_drbg, mbedtls_entropy_func, &entropy, (const uint8_t*) &pers, 4 ); if (0 == ret) { switch (c) { #if defined(WRAPPED_ASYM_RSA) case Cipher::ASYM_RSA: { ret = mbedtls_pk_setup(&key, mbedtls_pk_info_from_type(MBEDTLS_PK_RSA)); if (0 == ret) { mbedtls_rsa_context* rsa = mbedtls_pk_rsa(key); ret = mbedtls_rsa_gen_key(rsa, mbedtls_ctr_drbg_random, &ctr_drbg, (int) key_type, 65537 ); if (0 == ret) { ret--; memset(pub, 0, *pub_len); memset(priv, 0, *priv_len); int written = mbedtls_pk_write_pubkey_der(&key, pub, *pub_len); if (0 < written) { *pub_len = written; written = mbedtls_pk_write_key_der(&key, priv, *priv_len); if (0 < written) { *priv_len = written; ret = 0; } } } } } break; #endif #if defined(MBEDTLS_ECDSA_C) case Cipher::ASYM_ECDSA: { ret = mbedtls_pk_setup(&key, mbedtls_pk_info_from_type(MBEDTLS_PK_ECKEY)); if (0 == ret) { mbedtls_ecp_keypair* ec_kp = mbedtls_pk_ec(key); ret = mbedtls_ecdsa_genkey(ec_kp, (mbedtls_ecp_group_id) key_type, mbedtls_ctr_drbg_random, &ctr_drbg ); if (0 == ret) { ret--; memset(pub, 0, *pub_len); memset(priv, 0, *priv_len); int written = mbedtls_pk_write_pubkey_der(&key, pub, *pub_len); if (0 < written) { *pub_len = written; written = mbedtls_pk_write_key_der(&key, priv, *priv_len); if (0 < written) { *priv_len = written; ret = 0; } } } } } break; #endif #if defined(MBEDTLS_ECP_C) case Cipher::ASYM_ECKEY: { ret = mbedtls_pk_setup(&key, mbedtls_pk_info_from_type(MBEDTLS_PK_ECKEY)); if (0 == ret) { mbedtls_ecp_keypair* ec_kp = mbedtls_pk_ec(key); ret = mbedtls_ecp_gen_key( (mbedtls_ecp_group_id) key_type, ec_kp, mbedtls_ctr_drbg_random, &ctr_drbg ); if (0 == ret) { ret--; memset(pub, 0, *pub_len); memset(priv, 0, *priv_len); int written = mbedtls_pk_write_pubkey_der(&key, pub, *pub_len); if (0 < written) { *pub_len = written; written = mbedtls_pk_write_key_der(&key, priv, *priv_len); if (0 < written) { *priv_len = written; ret = 0; } } } } } break; #endif default: break; } } mbedtls_pk_free(&key); mbedtls_ctr_drbg_free(&ctr_drbg); return ret; }