ProtocolError DTLSMessageChannel::setup_context() { int ret; mbedtls_ssl_free(&ssl_context); ret = mbedtls_ssl_setup(&ssl_context, &conf); EXIT_ERROR(ret, "unable to setup SSL context"); mbedtls_ssl_set_timer_cb(&ssl_context, &timer, mbedtls_timing_set_delay, mbedtls_timing_get_delay); mbedtls_ssl_set_bio(&ssl_context, this, &DTLSMessageChannel::send_, &DTLSMessageChannel::recv_, NULL); if ((ssl_context.session_negotiate->peer_cert = (mbedtls_x509_crt*)calloc(1, sizeof(mbedtls_x509_crt))) == NULL) { ERROR("unable to allocate certificate storage"); return INSUFFICIENT_STORAGE; } mbedtls_x509_crt_init(ssl_context.session_negotiate->peer_cert); ret = mbedtls_pk_parse_public_key(&ssl_context.session_negotiate->peer_cert->pk, server_public, server_public_len); if (ret) { WARN("unable to parse negotiated public key: -%x", -ret); return IO_ERROR; } return NO_ERROR; }
static value key_from_pem(value data, value pub, value pass){ mbedtls_pk_context *pk; int r, len; value v; unsigned char *buf; val_check(data, string); val_check(pub, bool); if (!val_is_null(pass)) val_check(pass, string); len = val_strlen(data)+1; buf = (unsigned char *)alloc(len); memcpy(buf, val_string(data), len-1); buf[len-1] = '\0'; pk = (mbedtls_pk_context *)alloc(sizeof(mbedtls_pk_context)); mbedtls_pk_init(pk); if( val_bool(pub) ) r = mbedtls_pk_parse_public_key( pk, buf, len ); else if( val_is_null(pass) ) r = mbedtls_pk_parse_key( pk, buf, len, NULL, 0 ); else r = mbedtls_pk_parse_key( pk, buf, len, (const unsigned char*)val_string(pass), val_strlen(pass) ); if( r != 0 ){ mbedtls_pk_free(pk); return ssl_error(r); } v = alloc_abstract(k_pkey,pk); val_gc(v,free_pkey); return v; }
int mbedtls_ecies_read_originator(unsigned char **p, const unsigned char *end, mbedtls_ecp_keypair **originator_keypair) { int result = 0; mbedtls_pk_context pk; size_t key_len = 0; if (originator_keypair == NULL || *originator_keypair != NULL) { return MBEDTLS_ERR_ECIES_BAD_INPUT_DATA; } INVOKE_AND_CHECK(result, asn1_get_tag_len(*p, end, &key_len) ); mbedtls_pk_init(&pk); INVOKE_AND_CHECK(result, mbedtls_pk_parse_public_key(&pk, *p, key_len) ); if (mbedtls_pk_can_do(&pk, MBEDTLS_PK_ECKEY) || mbedtls_pk_can_do(&pk, MBEDTLS_PK_ECKEY_DH) || mbedtls_pk_can_do(&pk, MBEDTLS_PK_ECDSA)) { *originator_keypair = mbedtls_pk_ec(pk); // SHOULD be released in client code. } else { mbedtls_pk_free(&pk); result = MBEDTLS_ERR_ECIES_MALFORMED_DATA; } *p += key_len; return result; }
result_t PKey::importFile(const char* filename, const char* password) { result_t hr; std::string data; int32_t ret; hr = fs_base::ac_readFile(filename, data); if (hr < 0) return hr; clear(); ret = mbedtls_pk_parse_key(&m_key, (const unsigned char *)data.c_str(), data.length() + 1, *password ? (unsigned char *)password : NULL, qstrlen(password)); if (ret == MBEDTLS_ERR_PK_KEY_INVALID_FORMAT) ret = mbedtls_pk_parse_public_key(&m_key, (const unsigned char *)data.c_str(), data.length() + 1); if (ret != 0) return CHECK_ERROR(_ssl::setError(ret)); return 0; }
/* * Load and parse a public key */ int mbedtls_pk_parse_public_keyfile( mbedtls_pk_context *ctx, const char *path ) { int ret; size_t n; unsigned char *buf; if( ( ret = mbedtls_pk_load_file( path, &buf, &n ) ) != 0 ) return( ret ); ret = mbedtls_pk_parse_public_key( ctx, buf, n ); mbedtls_zeroize( buf, n ); mbedtls_free( buf ); return( ret ); }
result_t PKey::importKey(const char *pemKey, const char *password) { int32_t ret; clear(); ret = mbedtls_pk_parse_key(&m_key, (unsigned char *)pemKey, qstrlen(pemKey) + 1, *password ? (unsigned char *)password : NULL, qstrlen(password) ); if (ret == MBEDTLS_ERR_PK_KEY_INVALID_FORMAT) ret = mbedtls_pk_parse_public_key(&m_key, (unsigned char *)pemKey, qstrlen(pemKey) + 1); if (ret != 0) return CHECK_ERROR(_ssl::setError(ret)); return 0; }
ProtocolError DTLSMessageChannel::init( const uint8_t* core_private, size_t core_private_len, const uint8_t* core_public, size_t core_public_len, const uint8_t* server_public, size_t server_public_len, const uint8_t* device_id, Callbacks& callbacks, message_id_t* coap_state) { init(); this->coap_state = coap_state; int ret; this->callbacks = callbacks; this->device_id = device_id; keys_checksum = compute_checksum(callbacks.calculate_crc, server_public, server_public_len, core_private, core_private_len); ret = mbedtls_ssl_config_defaults(&conf, MBEDTLS_SSL_IS_CLIENT, MBEDTLS_SSL_TRANSPORT_DATAGRAM, MBEDTLS_SSL_PRESET_DEFAULT); EXIT_ERROR(ret, "unable to configure defaults"); mbedtls_ssl_conf_handshake_timeout(&conf, 3000, 6000); mbedtls_ssl_conf_rng(&conf, dtls_rng, this); mbedtls_ssl_conf_dbg(&conf, my_debug, nullptr); mbedtls_ssl_conf_min_version(&conf, MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3); ret = mbedtls_pk_parse_public_key(&pkey, core_public, core_public_len); EXIT_ERROR(ret, "unable to parse device public key"); ret = mbedtls_pk_parse_key(&pkey, core_private, core_private_len, NULL, 0); EXIT_ERROR(ret, "unable to parse device private key"); ret = mbedtls_ssl_conf_own_cert(&conf, &clicert, &pkey); EXIT_ERROR(ret, "unable to configure own certificate"); mbedtls_ssl_conf_authmode(&conf, MBEDTLS_SSL_VERIFY_OPTIONAL); static int ssl_cert_types[] = { MBEDTLS_TLS_CERT_TYPE_RAW_PUBLIC_KEY, MBEDTLS_TLS_CERT_TYPE_NONE }; mbedtls_ssl_conf_client_certificate_types(&conf, ssl_cert_types); mbedtls_ssl_conf_server_certificate_types(&conf, ssl_cert_types); mbedtls_ssl_conf_certificate_receive(&conf, MBEDTLS_SSL_RECEIVE_CERTIFICATE_DISABLED); this->server_public = new uint8_t[server_public_len]; memcpy(this->server_public, server_public, server_public_len); this->server_public_len = server_public_len; return NO_ERROR; }
static value key_from_der( value data, value pub ){ mbedtls_pk_context *pk; int r; value v; val_check(data, string); val_check(pub, bool); pk = (mbedtls_pk_context *)alloc(sizeof(mbedtls_pk_context)); mbedtls_pk_init(pk); if( val_bool(pub) ) r = mbedtls_pk_parse_public_key( pk, (const unsigned char*)val_string(data), val_strlen(data) ); else r = mbedtls_pk_parse_key( pk, (const unsigned char*)val_string(data), val_strlen(data), NULL, 0 ); if( r != 0 ){ mbedtls_pk_free(pk); return ssl_error(r); } v = alloc_abstract(k_pkey, pk); val_gc(v,free_pkey); return v; }
result_t PKey::importKey(Buffer_base *DerKey, const char *password) { int32_t ret; std::string key; DerKey->toString(key); clear(); ret = mbedtls_pk_parse_key(&m_key, (unsigned char *)key.c_str(), key.length() + 1, *password ? (unsigned char *)password : NULL, qstrlen(password)); if (ret == MBEDTLS_ERR_PK_KEY_INVALID_FORMAT) ret = mbedtls_pk_parse_public_key(&m_key, (unsigned char *)key.c_str(), key.length() + 1); if (ret != 0) return CHECK_ERROR(_ssl::setError(ret)); return 0; }
kaa_error_t rsa_encrypt(const uint8_t *key, size_t key_size, const uint8_t *input, size_t input_len, uint8_t *output) { if (key == NULL || key_size == 0) { return KAA_ERR_BADPARAM; } mbedtls_pk_context pk; mbedtls_entropy_context entropy; mbedtls_ctr_drbg_context ctr_drbg; const uint8_t pers[] = "key_gen"; mbedtls_pk_init(&pk); if (mbedtls_pk_parse_public_key(&pk, key, key_size) != 0) { return KAA_ERR_INVALID_PUB_KEY; } mbedtls_ctr_drbg_init(&ctr_drbg); mbedtls_entropy_init(&entropy); int ret = mbedtls_ctr_drbg_seed(&ctr_drbg, mbedtls_entropy_func, &entropy, pers, sizeof(pers) - 1); if (!ret) { ret = mbedtls_rsa_rsaes_pkcs1_v15_encrypt(mbedtls_pk_rsa(pk), mbedtls_ctr_drbg_random, &ctr_drbg, MBEDTLS_RSA_PUBLIC, input_len, input, output); } mbedtls_ctr_drbg_free(&ctr_drbg); mbedtls_entropy_free(&entropy); mbedtls_pk_free(&pk); if (ret) { return KAA_ERR_GENERIC; } return KAA_ERR_NONE; }
/** * Wrapper for sign-verify operations. * * @param Cipher Algorithm class * @param CryptoKey Key parameters * @param Hashes Digest alg to use. * @param uint8_t* Buffer to be signed/verified... * @param int ...and its length. * @param uint8_t* Buffer to hold signature... * @param int* ...and its length. * @param uint8_t* Buffer holding the key... * @param int ...and its length. * @param uint32_t Options to the operations. * @return 0 if the operation completed successfully. */ int __attribute__((weak)) wrapped_sign_verify(Cipher c, CryptoKey k, Hashes h, uint8_t* msg, int msg_len, uint8_t* sig, size_t* sig_len, uint8_t* key, int key_len, uint32_t opts) { if (keygen_deferred_handling(k)) { // If overriden by user implementation. return _s_v_overrides[k](c, k, h, msg, msg_len, sig, sig_len, key, key_len, opts); } int ret = -1; // Failure by default. uint8_t* hash; int hashlen; if (Hashes::NONE != h) { hashlen = get_digest_output_length(h); hash = (uint8_t*) alloca(hashlen); if (hash) { ret = wrapped_hash(msg, msg_len, hash, h); } } else { // This is the no-digest case. hashlen = msg_len; hash = msg; ret = 0; // TODO: Fail if size is greater than the maximum input length for the Key type. } if (0 == ret) { // If we are here, the hashing operation worked. Now we case-off on key/algo. mbedtls_pk_context k_ctx; mbedtls_pk_init(&k_ctx); 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(&k_ctx, mbedtls_pk_info_from_type(MBEDTLS_PK_RSA)); if (opts & OP_SIGN) { ret = mbedtls_pk_setup(&k_ctx, mbedtls_pk_info_from_type(MBEDTLS_PK_RSA)); if (0 == ret) { ret = mbedtls_pk_parse_key(&k_ctx, key, key_len, nullptr, 0); if (0 == ret) { ret = mbedtls_pk_sign( &k_ctx, (mbedtls_md_type_t) h, hash, hashlen, sig, sig_len, mbedtls_ctr_drbg_random, &ctr_drbg ); } } } else { ret = mbedtls_pk_parse_public_key(&k_ctx, key, key_len); if (0 == ret) { ret = mbedtls_pk_verify( &k_ctx, (mbedtls_md_type_t) h, hash, hashlen, sig, *sig_len ); } } break; #endif #if defined(MBEDTLS_ECDSA_C) case Cipher::ASYM_ECDSA: if (opts & OP_SIGN) { ret = mbedtls_pk_setup(&k_ctx, mbedtls_pk_info_from_type(MBEDTLS_PK_ECDSA)); if (0 == ret) { ret = mbedtls_pk_parse_key(&k_ctx, key, key_len, nullptr, 0); if (0 == ret) { ret = mbedtls_pk_sign( &k_ctx, (mbedtls_md_type_t) h, hash, hashlen, sig, sig_len, mbedtls_ctr_drbg_random, &ctr_drbg ); } } } else { ret = mbedtls_pk_parse_public_key(&k_ctx, key, key_len); if (0 == ret) { ret = mbedtls_pk_verify( &k_ctx, (mbedtls_md_type_t) h, hash, hashlen, sig, *sig_len ); } } break; #endif #if defined(MBEDTLS_ECP_C) case Cipher::ASYM_ECKEY: if (opts & OP_SIGN) { ret = mbedtls_pk_setup(&k_ctx, mbedtls_pk_info_from_type(MBEDTLS_PK_ECKEY)); if (0 == ret) { ret = mbedtls_pk_parse_key(&k_ctx, key, key_len, nullptr, 0); if (0 == ret) { ret = mbedtls_pk_sign( &k_ctx, (mbedtls_md_type_t) h, hash, hashlen, sig, sig_len, mbedtls_ctr_drbg_random, &ctr_drbg ); } } } else { ret = mbedtls_pk_parse_public_key(&k_ctx, key, key_len); if (0 == ret) { ret = mbedtls_pk_verify( &k_ctx, (mbedtls_md_type_t) h, hash, hashlen, sig, *sig_len ); } } break; #endif default: break; } } } return ret; }