static void deinit_keys(gnutls_session_t session) { gnutls_pk_params_release(&session->key.ecdh_params); gnutls_pk_params_release(&session->key.dh_params); zrelease_temp_mpi_key(&session->key.ecdh_x); zrelease_temp_mpi_key(&session->key.ecdh_y); _gnutls_free_temp_key_datum(&session->key.ecdhx); zrelease_temp_mpi_key(&session->key.client_Y); /* SRP */ zrelease_temp_mpi_key(&session->key.srp_p); zrelease_temp_mpi_key(&session->key.srp_g); zrelease_temp_mpi_key(&session->key.srp_key); zrelease_temp_mpi_key(&session->key.u); zrelease_temp_mpi_key(&session->key.a); zrelease_temp_mpi_key(&session->key.x); zrelease_temp_mpi_key(&session->key.A); zrelease_temp_mpi_key(&session->key.B); zrelease_temp_mpi_key(&session->key.b); _gnutls_free_temp_key_datum(&session->key.key); _gnutls_free_temp_key_datum(&session->key.key); }
/** * gnutls_privkey_export_ecc_raw: * @key: Holds the public key * @curve: will hold the curve * @x: will hold the x coordinate * @y: will hold the y coordinate * @k: will hold the private key * * This function will export the ECC private key's parameters found * in the given structure. The new parameters will be allocated using * gnutls_malloc() and will be stored in the appropriate datum. * * Returns: %GNUTLS_E_SUCCESS on success, otherwise a negative error code. * * Since: 3.3.0 **/ int gnutls_privkey_export_ecc_raw(gnutls_privkey_t key, gnutls_ecc_curve_t * curve, gnutls_datum_t * x, gnutls_datum_t * y, gnutls_datum_t * k) { gnutls_pk_params_st params; int ret; if (key == NULL) { gnutls_assert(); return GNUTLS_E_INVALID_REQUEST; } gnutls_pk_params_init(¶ms); ret = _gnutls_privkey_get_mpis(key, ¶ms); if (ret < 0) return gnutls_assert_val(ret); ret = _gnutls_params_get_ecc_raw(¶ms, curve, x, y, k); gnutls_pk_params_release(¶ms); return ret; }
/** * gnutls_privkey_export_dsa_raw: * @key: Holds the public key * @p: will hold the p * @q: will hold the q * @g: will hold the g * @y: will hold the y * @x: will hold the x * * This function will export the DSA private key's parameters found * in the given structure. The new parameters will be allocated using * gnutls_malloc() and will be stored in the appropriate datum. * * Returns: %GNUTLS_E_SUCCESS on success, otherwise a negative error code. * * Since: 3.3.0 **/ int gnutls_privkey_export_dsa_raw(gnutls_privkey_t key, gnutls_datum_t * p, gnutls_datum_t * q, gnutls_datum_t * g, gnutls_datum_t * y, gnutls_datum_t * x) { gnutls_pk_params_st params; int ret; if (key == NULL) { gnutls_assert(); return GNUTLS_E_INVALID_REQUEST; } gnutls_pk_params_init(¶ms); ret = _gnutls_privkey_get_mpis(key, ¶ms); if (ret < 0) return gnutls_assert_val(ret); ret = _gnutls_params_get_dsa_raw(¶ms, p, q, g, y, x); gnutls_pk_params_release(¶ms); return ret; }
/** * gnutls_deinit: * @session: is a #gnutls_session_t structure. * * This function clears all buffers associated with the @session. * This function will also remove session data from the session * database if the session was terminated abnormally. **/ void gnutls_deinit (gnutls_session_t session) { unsigned int i; if (session == NULL) return; _gnutls_rnd_refresh(); /* remove auth info firstly */ _gnutls_free_auth_info (session); _gnutls_handshake_internal_state_clear (session); _gnutls_handshake_io_buffer_clear (session); _gnutls_ext_free_session_data (session); for (i = 0; i < MAX_EPOCH_INDEX; i++) if (session->record_parameters[i] != NULL) { _gnutls_epoch_free (session, session->record_parameters[i]); session->record_parameters[i] = NULL; } _gnutls_buffer_clear (&session->internals.handshake_hash_buffer); _gnutls_buffer_clear (&session->internals.hb_remote_data); _gnutls_buffer_clear (&session->internals.hb_local_data); _gnutls_buffer_clear (&session->internals.record_presend_buffer); _mbuffer_head_clear (&session->internals.record_buffer); _mbuffer_head_clear (&session->internals.record_recv_buffer); _mbuffer_head_clear (&session->internals.record_send_buffer); gnutls_credentials_clear (session); _gnutls_selected_certs_deinit (session); gnutls_pk_params_release(&session->key.ecdh_params); _gnutls_mpi_release (&session->key.ecdh_x); _gnutls_mpi_release (&session->key.ecdh_y); _gnutls_mpi_release (&session->key.KEY); _gnutls_mpi_release (&session->key.client_Y); _gnutls_mpi_release (&session->key.client_p); _gnutls_mpi_release (&session->key.client_g); _gnutls_mpi_release (&session->key.u); _gnutls_mpi_release (&session->key.a); _gnutls_mpi_release (&session->key.x); _gnutls_mpi_release (&session->key.A); _gnutls_mpi_release (&session->key.B); _gnutls_mpi_release (&session->key.b); /* RSA */ _gnutls_mpi_release (&session->key.rsa[0]); _gnutls_mpi_release (&session->key.rsa[1]); _gnutls_mpi_release (&session->key.dh_secret); gnutls_free (session); }
static int set_dh_pk_params(gnutls_session_t session, bigint_t g, bigint_t p, unsigned q_bits) { /* just in case we are resuming a session */ gnutls_pk_params_release(&session->key.proto.tls12.dh.params); gnutls_pk_params_init(&session->key.proto.tls12.dh.params); session->key.proto.tls12.dh.params.params[DH_G] = _gnutls_mpi_copy(g); if (session->key.proto.tls12.dh.params.params[DH_G] == NULL) return gnutls_assert_val(GNUTLS_E_MEMORY_ERROR); session->key.proto.tls12.dh.params.params[DH_P] = _gnutls_mpi_copy(p); if (session->key.proto.tls12.dh.params.params[DH_P] == NULL) { _gnutls_mpi_release(&session->key.proto.tls12.dh.params.params[DH_G]); return gnutls_assert_val(GNUTLS_E_MEMORY_ERROR); } session->key.proto.tls12.dh.params.params_nr = 3; /* include empty q */ session->key.proto.tls12.dh.params.algo = GNUTLS_PK_DH; session->key.proto.tls12.dh.params.qbits = q_bits; return 0; }
/* verifies if the certificate is properly signed. * returns GNUTLS_E_PK_VERIFY_SIG_FAILED on failure and 1 on success. * * 'data' is the signed data * 'signature' is the signature! */ int _gnutls_x509_verify_data (gnutls_digest_algorithm_t algo, const gnutls_datum_t * data, const gnutls_datum_t * signature, gnutls_x509_crt_t issuer) { gnutls_pk_params_st issuer_params; int ret; /* Read the MPI parameters from the issuer's certificate. */ ret = _gnutls_x509_crt_get_mpis (issuer, &issuer_params); if (ret < 0) { gnutls_assert (); return ret; } ret = pubkey_verify_data (gnutls_x509_crt_get_pk_algorithm (issuer, NULL), algo, data, signature, &issuer_params); if (ret < 0) { gnutls_assert (); } /* release all allocated MPIs */ gnutls_pk_params_release(&issuer_params); return ret; }
/** * gnutls_pubkey_deinit: * @key: The key to be deinitialized * * This function will deinitialize a public key structure. * * Since: 2.12.0 **/ void gnutls_pubkey_deinit(gnutls_pubkey_t key) { if (!key) return; gnutls_pk_params_release(&key->params); gnutls_free(key); }
/* some generic pk functions */ static int _generate_params (int algo, bigint_t * resarr, unsigned int *resarr_len, int bits) { gnutls_pk_params_st params; int ret; unsigned int i; ret = _gnutls_pk_ops.generate (algo, bits, ¶ms); if (ret < 0) { gnutls_assert (); return ret; } if (resarr && resarr_len && *resarr_len >= params.params_nr) { *resarr_len = params.params_nr; for (i = 0; i < params.params_nr; i++) resarr[i] = params.params[i]; } else { gnutls_pk_params_release(¶ms); gnutls_assert (); return GNUTLS_E_INVALID_REQUEST; } return 0; }
void _gnutls_x509_privkey_reinit(gnutls_x509_privkey_t key) { gnutls_pk_params_clear(&key->params); gnutls_pk_params_release(&key->params); asn1_delete_structure2(&key->key, ASN1_DELETE_FLAG_ZEROIZE); key->key = ASN1_TYPE_EMPTY; }
/** * gnutls_privkey_export_rsa_raw: * @key: Holds the certificate * @m: will hold the modulus * @e: will hold the public exponent * @d: will hold the private exponent * @p: will hold the first prime (p) * @q: will hold the second prime (q) * @u: will hold the coefficient * @e1: will hold e1 = d mod (p-1) * @e2: will hold e2 = d mod (q-1) * * This function will export the RSA private key's parameters found * in the given structure. The new parameters will be allocated using * gnutls_malloc() and will be stored in the appropriate datum. * * Returns: %GNUTLS_E_SUCCESS on success, otherwise a negative error code. * * Since: 3.3.0 **/ int gnutls_privkey_export_rsa_raw(gnutls_privkey_t key, gnutls_datum_t * m, gnutls_datum_t * e, gnutls_datum_t * d, gnutls_datum_t * p, gnutls_datum_t * q, gnutls_datum_t * u, gnutls_datum_t * e1, gnutls_datum_t * e2) { gnutls_pk_params_st params; int ret; if (key == NULL) { gnutls_assert(); return GNUTLS_E_INVALID_REQUEST; } gnutls_pk_params_init(¶ms); ret = _gnutls_privkey_get_mpis(key, ¶ms); if (ret < 0) return gnutls_assert_val(ret); ret = _gnutls_params_get_rsa_raw(¶ms, m, e, d, p, q, u, e1, e2); gnutls_pk_params_release(¶ms); return ret; }
/*- * _gnutls_openpgp_privkey_decrypt_data: * @key: Holds the key * @flags: (0) for now * @ciphertext: holds the data to be decrypted * @plaintext: will contain newly allocated plaintext * * This function will sign the given hash using the private key. You * should use gnutls_openpgp_privkey_set_preferred_key_id() before * calling this function to set the subkey to use. * * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a * negative error value. -*/ int _gnutls_openpgp_privkey_decrypt_data (gnutls_openpgp_privkey_t key, unsigned int flags, const gnutls_datum_t * ciphertext, gnutls_datum_t * plaintext) { int result, i; gnutls_pk_params_st params; int pk_algorithm; uint8_t keyid[GNUTLS_OPENPGP_KEYID_SIZE]; char buf[2*GNUTLS_OPENPGP_KEYID_SIZE+1]; if (key == NULL) { gnutls_assert (); return GNUTLS_E_INVALID_REQUEST; } result = gnutls_openpgp_privkey_get_preferred_key_id (key, keyid); if (result == 0) { uint32_t kid[2]; KEYID_IMPORT (kid, keyid); _gnutls_hard_log("Decrypting using PGP key ID %s\n", _gnutls_bin2hex(keyid, GNUTLS_OPENPGP_KEYID_SIZE, buf, sizeof(buf), NULL)); result = _gnutls_openpgp_privkey_get_mpis (key, kid, ¶ms); i = gnutls_openpgp_privkey_get_subkey_idx (key, keyid); pk_algorithm = gnutls_openpgp_privkey_get_subkey_pk_algorithm (key, i, NULL); } else { _gnutls_hard_log("Decrypting using master PGP key\n"); pk_algorithm = gnutls_openpgp_privkey_get_pk_algorithm (key, NULL); result = _gnutls_openpgp_privkey_get_mpis (key, NULL, ¶ms); } if (result < 0) { gnutls_assert (); return result; } result = _gnutls_pk_decrypt (pk_algorithm, plaintext, ciphertext, ¶ms); gnutls_pk_params_clear(¶ms); gnutls_pk_params_release(¶ms); if (result < 0) return gnutls_assert_val(result); return 0; }
/** * gnutls_x509_privkey_generate: * @key: should contain a #gnutls_x509_privkey_t structure * @algo: is one of the algorithms in #gnutls_pk_algorithm_t. * @bits: the size of the modulus * @flags: unused for now. Must be 0. * * This function will generate a random private key. Note that this * function must be called on an empty private key. * * Note that when generating an elliptic curve key, the curve * can be substituted in the place of the bits parameter using the * GNUTLS_CURVE_TO_BITS() macro. * * For DSA keys, if the subgroup size needs to be specified check * the GNUTLS_SUBGROUP_TO_BITS() macro. * * Do not set the number of bits directly, use gnutls_sec_param_to_pk_bits(). * * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a * negative error value. **/ int gnutls_x509_privkey_generate(gnutls_x509_privkey_t key, gnutls_pk_algorithm_t algo, unsigned int bits, unsigned int flags) { int ret; if (key == NULL) { gnutls_assert(); return GNUTLS_E_INVALID_REQUEST; } gnutls_pk_params_init(&key->params); if (algo == GNUTLS_PK_EC) { if (GNUTLS_BITS_ARE_CURVE(bits)) bits = GNUTLS_BITS_TO_CURVE(bits); else bits = _gnutls_ecc_bits_to_curve(bits); } ret = _gnutls_pk_generate_params(algo, bits, &key->params); if (ret < 0) { gnutls_assert(); return ret; } ret = _gnutls_pk_generate_keys(algo, bits, &key->params); if (ret < 0) { gnutls_assert(); return ret; } #ifndef ENABLE_FIPS140 ret = _gnutls_pk_verify_priv_params(algo, &key->params); #else ret = pct_test(algo, &key->params); #endif if (ret < 0) { gnutls_assert(); return ret; } ret = _gnutls_asn1_encode_privkey(algo, &key->key, &key->params); if (ret < 0) { gnutls_assert(); goto cleanup; } key->pk_algorithm = algo; return 0; cleanup: key->pk_algorithm = GNUTLS_PK_UNKNOWN; gnutls_pk_params_clear(&key->params); gnutls_pk_params_release(&key->params); return ret; }
/* Returns the public key of the private key (if possible) */ int _gnutls_privkey_get_public_mpis(gnutls_privkey_t key, gnutls_pk_params_st * params) { int ret; gnutls_pk_algorithm_t pk = gnutls_privkey_get_pk_algorithm(key, NULL); switch (key->type) { #ifdef ENABLE_OPENPGP case GNUTLS_PRIVKEY_OPENPGP: { gnutls_pk_params_st tmp_params; uint32_t kid[2]; uint8_t keyid[GNUTLS_OPENPGP_KEYID_SIZE]; ret = gnutls_openpgp_privkey_get_preferred_key_id (key->key.openpgp, keyid); if (ret == 0) { KEYID_IMPORT(kid, keyid); ret = _gnutls_openpgp_privkey_get_mpis(key-> key. openpgp, kid, &tmp_params); } else ret = _gnutls_openpgp_privkey_get_mpis(key-> key. openpgp, NULL, &tmp_params); if (ret < 0) { gnutls_assert(); return ret; } ret = privkey_to_pubkey(pk, &tmp_params, params); gnutls_pk_params_release(&tmp_params); } break; #endif case GNUTLS_PRIVKEY_X509: ret = privkey_to_pubkey(pk, &key->key.x509->params, params); break; default: gnutls_assert(); return GNUTLS_E_INVALID_REQUEST; } return ret; }
/* If the psk flag is set, then an empty psk_identity_hint will * be inserted */ int _gnutls_ecdh_common_print_server_kx(gnutls_session_t session, gnutls_buffer_st * data, gnutls_ecc_curve_t curve) { uint8_t p; int ret; gnutls_datum_t out; if (curve == GNUTLS_ECC_CURVE_INVALID) return gnutls_assert_val(GNUTLS_E_ECC_NO_SUPPORTED_CURVES); /* just in case we are resuming a session */ gnutls_pk_params_release(&session->key.ecdh_params); gnutls_pk_params_init(&session->key.ecdh_params); /* curve type */ p = 3; ret = _gnutls_buffer_append_data(data, &p, 1); if (ret < 0) return gnutls_assert_val(ret); ret = _gnutls_buffer_append_prefix(data, 16, _gnutls_ecc_curve_get_tls_id (curve)); if (ret < 0) return gnutls_assert_val(ret); /* generate temporal key */ ret = _gnutls_pk_generate_keys(GNUTLS_PK_EC, curve, &session->key.ecdh_params); if (ret < 0) return gnutls_assert_val(ret); ret = _gnutls_ecc_ansi_x963_export(curve, session->key.ecdh_params. params[ECC_X] /* x */ , session->key.ecdh_params. params[ECC_Y] /* y */ , &out); if (ret < 0) return gnutls_assert_val(ret); ret = _gnutls_buffer_append_data_prefix(data, 8, out.data, out.size); _gnutls_free_datum(&out); if (ret < 0) return gnutls_assert_val(ret); return data->length; }
/** * gnutls_x509_privkey_deinit: * @key: The structure to be deinitialized * * This function will deinitialize a private key structure. **/ void gnutls_x509_privkey_deinit (gnutls_x509_privkey_t key) { if (!key) return; gnutls_pk_params_release(&key->params); asn1_delete_structure (&key->key); gnutls_free (key); }
/** * gnutls_x509_privkey_import_ecc_raw: * @key: The structure to store the parsed key * @curve: holds the curve * @x: holds the x * @y: holds the y * @k: holds the k * * This function will convert the given elliptic curve parameters to the * native #gnutls_x509_privkey_t format. The output will be stored * in @key. * * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a * negative error value. * * Since: 3.0 **/ int gnutls_x509_privkey_import_ecc_raw (gnutls_x509_privkey_t key, gnutls_ecc_curve_t curve, const gnutls_datum_t * x, const gnutls_datum_t * y, const gnutls_datum_t * k) { int ret; if (key == NULL) { gnutls_assert (); return GNUTLS_E_INVALID_REQUEST; } key->params.flags = curve; ret = _gnutls_ecc_curve_fill_params(curve, &key->params); if (ret < 0) return gnutls_assert_val(ret); if (_gnutls_mpi_scan_nz (&key->params.params[ECC_X], x->data, x->size)) { gnutls_assert (); ret = GNUTLS_E_MPI_SCAN_FAILED; goto cleanup; } key->params.params_nr++; if (_gnutls_mpi_scan_nz (&key->params.params[ECC_Y], y->data, y->size)) { gnutls_assert (); ret = GNUTLS_E_MPI_SCAN_FAILED; goto cleanup; } key->params.params_nr++; if (_gnutls_mpi_scan_nz (&key->params.params[ECC_K], k->data, k->size)) { gnutls_assert (); ret = GNUTLS_E_MPI_SCAN_FAILED; goto cleanup; } key->params.params_nr++; key->pk_algorithm = GNUTLS_PK_EC; return 0; cleanup: gnutls_pk_params_release(&key->params); return ret; }
/** * gnutls_pubkey_import_privkey: * @key: The public key * @pkey: The private key * @usage: GNUTLS_KEY_* key usage flags. * @flags: should be zero * * Imports the public key from a private. This function will import * the given public key to the abstract #gnutls_pubkey_t type. * * Note that in certain keys this operation may not be possible, e.g., * in other than RSA PKCS#11 keys. * * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a * negative error value. * * Since: 2.12.0 **/ int gnutls_pubkey_import_privkey(gnutls_pubkey_t key, gnutls_privkey_t pkey, unsigned int usage, unsigned int flags) { gnutls_pk_params_release(&key->params); gnutls_pk_params_init(&key->params); key->pk_algorithm = gnutls_privkey_get_pk_algorithm(pkey, &key->bits); key->key_usage = usage; return _gnutls_privkey_get_public_mpis(pkey, &key->params); }
static int calc_ecdh_key( gnutls_session_t session, gnutls_datum_t * psk_key) { gnutls_pk_params_st pub; int ret; memset(&pub,0,sizeof(pub)); pub.params[ECC_PRIME] = session->key.ecdh_params.params[ECC_PRIME]; pub.params[ECC_ORDER] = session->key.ecdh_params.params[ECC_ORDER]; pub.params[ECC_A] = session->key.ecdh_params.params[ECC_A]; pub.params[ECC_B] = session->key.ecdh_params.params[ECC_B]; pub.params[ECC_GX] = session->key.ecdh_params.params[ECC_GX]; pub.params[ECC_GY] = session->key.ecdh_params.params[ECC_GY]; pub.params[ECC_X] = session->key.ecdh_x; pub.params[ECC_Y] = session->key.ecdh_y; if (psk_key == NULL) ret = _gnutls_pk_derive(GNUTLS_PK_EC, &session->key.key, &session->key.ecdh_params, &pub); else { gnutls_datum_t tmp_dh_key; ret = _gnutls_pk_derive(GNUTLS_PK_EC, &tmp_dh_key, &session->key.ecdh_params, &pub); if (ret < 0) { ret = gnutls_assert_val(ret); goto cleanup; } ret = _gnutls_set_psk_session_key (session, psk_key, &tmp_dh_key); _gnutls_free_datum (&tmp_dh_key); } if (ret < 0) { ret = gnutls_assert_val(ret); goto cleanup; } ret = 0; cleanup: /* no longer needed */ _gnutls_mpi_release (&session->key.ecdh_x); _gnutls_mpi_release (&session->key.ecdh_y); gnutls_pk_params_release( &session->key.ecdh_params); return ret; }
static int calc_ecdh_key(gnutls_session_t session, gnutls_datum_t * psk_key, gnutls_ecc_curve_t curve) { gnutls_pk_params_st pub; int ret; gnutls_pk_params_init(&pub); pub.params[ECC_X] = session->key.ecdh_x; pub.params[ECC_Y] = session->key.ecdh_y; pub.flags = curve; if (psk_key == NULL) { ret = _gnutls_pk_derive(GNUTLS_PK_EC, &session->key.key, &session->key.ecdh_params, &pub); } else { gnutls_datum_t tmp_dh_key; ret = _gnutls_pk_derive(GNUTLS_PK_EC, &tmp_dh_key, &session->key.ecdh_params, &pub); if (ret < 0) { ret = gnutls_assert_val(ret); goto cleanup; } ret = _gnutls_set_psk_session_key(session, psk_key, &tmp_dh_key); _gnutls_free_temp_key_datum(&tmp_dh_key); } if (ret < 0) { ret = gnutls_assert_val(ret); goto cleanup; } ret = 0; cleanup: /* no longer needed */ _gnutls_mpi_release(&session->key.ecdh_x); _gnutls_mpi_release(&session->key.ecdh_y); gnutls_pk_params_release(&session->key.ecdh_params); return ret; }
/* Reads and returns the PK algorithm of the given certificate-like * ASN.1 structure. src_name should be something like "tbsCertificate.subjectPublicKeyInfo". */ int _gnutls_x509_get_pk_algorithm (ASN1_TYPE src, const char *src_name, unsigned int *bits) { int result; int algo; char oid[64]; int len; gnutls_pk_params_st params; char name[128]; gnutls_pk_params_init(¶ms); _asnstr_append_name (name, sizeof (name), src_name, ".algorithm.algorithm"); len = sizeof (oid); result = asn1_read_value (src, name, oid, &len); if (result != ASN1_SUCCESS) { gnutls_assert (); return _gnutls_asn2err (result); } algo = _gnutls_x509_oid2pk_algorithm (oid); if (algo == GNUTLS_PK_UNKNOWN) { _gnutls_debug_log ("%s: unknown public key algorithm: %s\n", __func__, oid); } if (bits == NULL) { return algo; } /* Now read the parameters' bits */ result = _gnutls_get_asn_mpis(src, src_name, ¶ms); if (result < 0) return gnutls_assert_val(result); bits[0] = pubkey_to_bits(algo, ¶ms); gnutls_pk_params_release(¶ms); return algo; }
int _gnutls_proc_ecdh_common_server_kx(gnutls_session_t session, uint8_t * data, size_t _data_size) { int i, ret, point_size; gnutls_ecc_curve_t curve; ssize_t data_size = _data_size; /* just in case we are resuming a session */ gnutls_pk_params_release(&session->key.ecdh_params); gnutls_pk_params_init(&session->key.ecdh_params); i = 0; DECR_LEN(data_size, 1); if (data[i++] != 3) return gnutls_assert_val(GNUTLS_E_ECC_NO_SUPPORTED_CURVES); DECR_LEN(data_size, 2); curve = _gnutls_tls_id_to_ecc_curve(_gnutls_read_uint16(&data[i])); i += 2; ret = _gnutls_session_supports_ecc_curve(session, curve); if (ret < 0) return gnutls_assert_val(ret); _gnutls_session_ecc_curve_set(session, curve); DECR_LEN(data_size, 1); point_size = data[i]; i++; DECR_LEN(data_size, point_size); ret = _gnutls_ecc_ansi_x963_import(&data[i], point_size, &session->key.ecdh_x, &session->key.ecdh_y); if (ret < 0) return gnutls_assert_val(ret); i += point_size; return i; }
/** * gnutls_x509_privkey_generate: * @key: should contain a #gnutls_x509_privkey_t structure * @algo: is one of the algorithms in #gnutls_pk_algorithm_t. * @bits: the size of the modulus * @flags: unused for now. Must be 0. * * This function will generate a random private key. Note that this * function must be called on an empty private key. * * Do not set the number of bits directly, use gnutls_sec_param_to_pk_bits(). * * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a * negative error value. **/ int gnutls_x509_privkey_generate (gnutls_x509_privkey_t key, gnutls_pk_algorithm_t algo, unsigned int bits, unsigned int flags) { int ret; if (key == NULL) { gnutls_assert (); return GNUTLS_E_INVALID_REQUEST; } gnutls_pk_params_init(&key->params); if (algo == GNUTLS_PK_EC) bits = _gnutls_ecc_bits_to_curve(bits); ret = _gnutls_pk_generate (algo, bits, &key->params); if (ret < 0) { gnutls_assert (); return ret; } ret = _gnutls_asn1_encode_privkey (algo, &key->key, &key->params); if (ret < 0) { gnutls_assert (); goto cleanup; } key->pk_algorithm = algo; return 0; cleanup: key->pk_algorithm = GNUTLS_PK_UNKNOWN; gnutls_pk_params_release(&key->params); return ret; }
/** * gnutls_privkey_verify_params: * @key: should contain a #gnutls_privkey_t type * * This function will verify the private key parameters. * * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a * negative error value. * * Since: 3.3.0 **/ int gnutls_privkey_verify_params(gnutls_privkey_t key) { gnutls_pk_params_st params; int ret; gnutls_pk_params_init(¶ms); ret = _gnutls_privkey_get_mpis(key, ¶ms); if (ret < 0) return gnutls_assert_val(ret); ret = _gnutls_pk_verify_priv_params(key->pk_algorithm, ¶ms); gnutls_pk_params_release(¶ms); if (ret < 0) { gnutls_assert(); return ret; } return 0; }
int _gnutls_privkey_get_public_mpis(gnutls_privkey_t key, gnutls_pk_params_st * params) { int ret; gnutls_pk_params_st tmp1; gnutls_pk_params_init(&tmp1); ret = _gnutls_privkey_get_mpis(key, &tmp1); if (ret < 0) return gnutls_assert_val(ret); ret = privkey_to_pubkey(key->pk_algorithm, &tmp1, params); gnutls_pk_params_release(&tmp1); if (ret < 0) gnutls_assert(); return ret; }
/** * gnutls_pubkey_import_x509_crq: * @key: The public key * @crq: The certificate to be imported * @flags: should be zero * * This function will import the given public key to the abstract * #gnutls_pubkey_t type. * * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a * negative error value. * * Since: 3.1.5 **/ int gnutls_pubkey_import_x509_crq(gnutls_pubkey_t key, gnutls_x509_crq_t crq, unsigned int flags) { int ret; gnutls_pk_params_release(&key->params); /* params initialized in _gnutls_x509_crq_get_mpis */ key->pk_algorithm = gnutls_x509_crq_get_pk_algorithm(crq, &key->bits); ret = gnutls_x509_crq_get_key_usage(crq, &key->key_usage, NULL); if (ret < 0) key->key_usage = 0; ret = _gnutls_x509_crq_get_mpis(crq, &key->params); if (ret < 0) { gnutls_assert(); return ret; } return 0; }
/** * gnutls_x509_privkey_import_dsa_raw: * @key: The structure to store the parsed key * @p: holds the p * @q: holds the q * @g: holds the g * @y: holds the y * @x: holds the x * * This function will convert the given DSA raw parameters to the * native #gnutls_x509_privkey_t format. The output will be stored * in @key. * * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a * negative error value. **/ int gnutls_x509_privkey_import_dsa_raw (gnutls_x509_privkey_t key, const gnutls_datum_t * p, const gnutls_datum_t * q, const gnutls_datum_t * g, const gnutls_datum_t * y, const gnutls_datum_t * x) { int ret; size_t siz = 0; if (key == NULL) { gnutls_assert (); return GNUTLS_E_INVALID_REQUEST; } siz = p->size; if (_gnutls_mpi_scan_nz (&key->params.params[0], p->data, siz)) { gnutls_assert (); ret = GNUTLS_E_MPI_SCAN_FAILED; goto cleanup; } siz = q->size; if (_gnutls_mpi_scan_nz (&key->params.params[1], q->data, siz)) { gnutls_assert (); ret = GNUTLS_E_MPI_SCAN_FAILED; goto cleanup; } siz = g->size; if (_gnutls_mpi_scan_nz (&key->params.params[2], g->data, siz)) { gnutls_assert (); ret = GNUTLS_E_MPI_SCAN_FAILED; goto cleanup; } siz = y->size; if (_gnutls_mpi_scan_nz (&key->params.params[3], y->data, siz)) { gnutls_assert (); ret = GNUTLS_E_MPI_SCAN_FAILED; goto cleanup; } siz = x->size; if (_gnutls_mpi_scan_nz (&key->params.params[4], x->data, siz)) { gnutls_assert (); ret = GNUTLS_E_MPI_SCAN_FAILED; goto cleanup; } ret = _gnutls_asn1_encode_privkey (GNUTLS_PK_DSA, &key->key, &key->params); if (ret < 0) { gnutls_assert (); goto cleanup; } key->params.params_nr = DSA_PRIVATE_PARAMS; key->pk_algorithm = GNUTLS_PK_DSA; return 0; cleanup: gnutls_pk_params_release(&key->params); return ret; }
/** * gnutls_x509_privkey_import_rsa_raw2: * @key: The structure to store the parsed key * @m: holds the modulus * @e: holds the public exponent * @d: holds the private exponent * @p: holds the first prime (p) * @q: holds the second prime (q) * @u: holds the coefficient * @e1: holds e1 = d mod (p-1) * @e2: holds e2 = d mod (q-1) * * This function will convert the given RSA raw parameters to the * native #gnutls_x509_privkey_t format. The output will be stored in * @key. * * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a * negative error value. **/ int gnutls_x509_privkey_import_rsa_raw2 (gnutls_x509_privkey_t key, const gnutls_datum_t * m, const gnutls_datum_t * e, const gnutls_datum_t * d, const gnutls_datum_t * p, const gnutls_datum_t * q, const gnutls_datum_t * u, const gnutls_datum_t * e1, const gnutls_datum_t * e2) { int ret; size_t siz = 0; if (key == NULL) { gnutls_assert (); return GNUTLS_E_INVALID_REQUEST; } gnutls_pk_params_init(&key->params); siz = m->size; if (_gnutls_mpi_scan_nz (&key->params.params[0], m->data, siz)) { gnutls_assert (); ret = GNUTLS_E_MPI_SCAN_FAILED; goto cleanup; } key->params.params_nr++; siz = e->size; if (_gnutls_mpi_scan_nz (&key->params.params[1], e->data, siz)) { gnutls_assert (); ret = GNUTLS_E_MPI_SCAN_FAILED; goto cleanup; } key->params.params_nr++; siz = d->size; if (_gnutls_mpi_scan_nz (&key->params.params[2], d->data, siz)) { gnutls_assert (); ret = GNUTLS_E_MPI_SCAN_FAILED; goto cleanup; } key->params.params_nr++; siz = p->size; if (_gnutls_mpi_scan_nz (&key->params.params[3], p->data, siz)) { gnutls_assert (); ret = GNUTLS_E_MPI_SCAN_FAILED; goto cleanup; } key->params.params_nr++; siz = q->size; if (_gnutls_mpi_scan_nz (&key->params.params[4], q->data, siz)) { gnutls_assert (); ret = GNUTLS_E_MPI_SCAN_FAILED; goto cleanup; } key->params.params_nr++; siz = u->size; if (_gnutls_mpi_scan_nz (&key->params.params[5], u->data, siz)) { gnutls_assert (); ret = GNUTLS_E_MPI_SCAN_FAILED; goto cleanup; } key->params.params_nr++; if (e1 && e2) { siz = e1->size; if (_gnutls_mpi_scan_nz (&key->params.params[6], e1->data, siz)) { gnutls_assert (); ret = GNUTLS_E_MPI_SCAN_FAILED; goto cleanup; } key->params.params_nr++; siz = e2->size; if (_gnutls_mpi_scan_nz (&key->params.params[7], e2->data, siz)) { gnutls_assert (); ret = GNUTLS_E_MPI_SCAN_FAILED; goto cleanup; } key->params.params_nr++; } ret = _gnutls_pk_fixup (GNUTLS_PK_RSA, GNUTLS_IMPORT, &key->params); if (ret < 0) { gnutls_assert (); goto cleanup; } ret = _gnutls_asn1_encode_privkey (GNUTLS_PK_RSA, &key->key, &key->params); if (ret < 0) { gnutls_assert (); goto cleanup; } key->params.params_nr = RSA_PRIVATE_PARAMS; key->pk_algorithm = GNUTLS_PK_RSA; return 0; cleanup: gnutls_pk_params_release(&key->params); return ret; }
static ASN1_TYPE decode_dsa_key (const gnutls_datum_t * raw_key, gnutls_x509_privkey_t pkey) { int result; ASN1_TYPE dsa_asn; if ((result = asn1_create_element (_gnutls_get_gnutls_asn (), "GNUTLS.DSAPrivateKey", &dsa_asn)) != ASN1_SUCCESS) { gnutls_assert (); return NULL; } pkey->params.params_nr = 0; result = asn1_der_decoding (&dsa_asn, raw_key->data, raw_key->size, NULL); if (result != ASN1_SUCCESS) { gnutls_assert (); goto error; } if ((result = _gnutls_x509_read_int (dsa_asn, "p", &pkey->params.params[0])) < 0) { gnutls_assert (); goto error; } pkey->params.params_nr++; if ((result = _gnutls_x509_read_int (dsa_asn, "q", &pkey->params.params[1])) < 0) { gnutls_assert (); goto error; } pkey->params.params_nr++; if ((result = _gnutls_x509_read_int (dsa_asn, "g", &pkey->params.params[2])) < 0) { gnutls_assert (); goto error; } pkey->params.params_nr++; if ((result = _gnutls_x509_read_int (dsa_asn, "Y", &pkey->params.params[3])) < 0) { gnutls_assert (); goto error; } pkey->params.params_nr++; if ((result = _gnutls_x509_read_int (dsa_asn, "priv", &pkey->params.params[4])) < 0) { gnutls_assert (); goto error; } pkey->params.params_nr++; return dsa_asn; error: asn1_delete_structure (&dsa_asn); gnutls_pk_params_release(&pkey->params); return NULL; }
/* Converts an ECC key to * an internal structure (gnutls_private_key) */ ASN1_TYPE _gnutls_privkey_decode_ecc_key (const gnutls_datum_t * raw_key, gnutls_x509_privkey_t pkey) { int ret; ASN1_TYPE pkey_asn; unsigned int version; char oid[MAX_OID_SIZE]; int oid_size; gnutls_datum out; gnutls_pk_params_init(&pkey->params); if ((ret = asn1_create_element (_gnutls_get_gnutls_asn (), "GNUTLS.ECPrivateKey", &pkey_asn)) != ASN1_SUCCESS) { gnutls_assert (); return NULL; } ret = asn1_der_decoding (&pkey_asn, raw_key->data, raw_key->size, NULL); if (ret != ASN1_SUCCESS) { gnutls_assert (); goto error; } ret = _gnutls_x509_read_uint (pkey_asn, "Version", &version); if (ret < 0) { gnutls_assert(); goto error; } if (version != 1) { _gnutls_debug_log("ECC private key version %u is not supported\n", version); gnutls_assert(); goto error; } /* read the curve */ oid_size = sizeof(oid); ret = asn1_read_value(pkey_asn, "parameters.namedCurve", oid, &oid_size); if (ret != ASN1_SUCCESS) { gnutls_assert (); goto error; } pkey->params.flags = _gnutls_oid_to_ecc_curve(oid); if (pkey->params.flags == GNUTLS_ECC_CURVE_INVALID) { _gnutls_debug_log("Curve %s is not supported\n", oid); gnutls_assert(); goto error; } ret = _gnutls_ecc_curve_fill_params(pkey->params.flags, &pkey->params); if (ret < 0) { gnutls_assert(); goto error; } /* read the public key */ ret = _gnutls_x509_read_value(pkey_asn, "publicKey", &out, 2); if (ret < 0) { gnutls_assert(); goto error; } ret = _gnutls_ecc_ansi_x963_import (out.data, out.size, &pkey->params.params[ECC_X], &pkey->params.params[ECC_Y]); _gnutls_free_datum(&out); if (ret < 0) { gnutls_assert(); goto error; } pkey->params.params_nr += 2; /* read the private key */ ret = _gnutls_x509_read_int (pkey_asn, "privateKey", &pkey->params.params[ECC_K]); if (ret < 0) { gnutls_assert(); goto error; } pkey->params.params_nr ++; return pkey_asn; error: asn1_delete_structure (&pkey_asn); gnutls_pk_params_release (&pkey->params); return NULL; }
/* Converts an RSA PKCS#1 key to * an internal structure (gnutls_private_key) */ ASN1_TYPE _gnutls_privkey_decode_pkcs1_rsa_key (const gnutls_datum_t * raw_key, gnutls_x509_privkey_t pkey) { int result; ASN1_TYPE pkey_asn; gnutls_pk_params_init(&pkey->params); if ((result = asn1_create_element (_gnutls_get_gnutls_asn (), "GNUTLS.RSAPrivateKey", &pkey_asn)) != ASN1_SUCCESS) { gnutls_assert (); return NULL; } result = asn1_der_decoding (&pkey_asn, raw_key->data, raw_key->size, NULL); if (result != ASN1_SUCCESS) { gnutls_assert (); goto error; } if ((result = _gnutls_x509_read_int (pkey_asn, "modulus", &pkey->params.params[0])) < 0) { gnutls_assert (); goto error; } pkey->params.params_nr++; if ((result = _gnutls_x509_read_int (pkey_asn, "publicExponent", &pkey->params.params[1])) < 0) { gnutls_assert (); goto error; } pkey->params.params_nr++; if ((result = _gnutls_x509_read_int (pkey_asn, "privateExponent", &pkey->params.params[2])) < 0) { gnutls_assert (); goto error; } pkey->params.params_nr++; if ((result = _gnutls_x509_read_int (pkey_asn, "prime1", &pkey->params.params[3])) < 0) { gnutls_assert (); goto error; } pkey->params.params_nr++; if ((result = _gnutls_x509_read_int (pkey_asn, "prime2", &pkey->params.params[4])) < 0) { gnutls_assert (); goto error; } pkey->params.params_nr++; if ((result = _gnutls_x509_read_int (pkey_asn, "coefficient", &pkey->params.params[5])) < 0) { gnutls_assert (); goto error; } pkey->params.params_nr++; if ((result = _gnutls_x509_read_int (pkey_asn, "exponent1", &pkey->params.params[6])) < 0) { gnutls_assert (); goto error; } pkey->params.params_nr++; if ((result = _gnutls_x509_read_int (pkey_asn, "exponent2", &pkey->params.params[7])) < 0) { gnutls_assert (); goto error; } pkey->params.params_nr++; result = _gnutls_pk_fixup (GNUTLS_PK_RSA, GNUTLS_IMPORT, &pkey->params); if (result < 0) { gnutls_assert (); goto error; } pkey->params.params_nr = RSA_PRIVATE_PARAMS; return pkey_asn; error: asn1_delete_structure (&pkey_asn); gnutls_pk_params_release (&pkey->params); return NULL; }