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; }
int _gnutls_dh_compute_key(gnutls_dh_params_t dh_params, const gnutls_datum_t *priv_key, const gnutls_datum_t *pub_key, const gnutls_datum_t *peer_key, gnutls_datum_t *Z) { gnutls_pk_params_st pub, priv; int ret; gnutls_pk_params_init(&pub); gnutls_pk_params_init(&priv); pub.algo = GNUTLS_PK_DH; if (_gnutls_mpi_init_scan_nz (&pub.params[DH_Y], peer_key->data, peer_key->size) != 0) { ret = gnutls_assert_val(GNUTLS_E_MPI_SCAN_FAILED); goto cleanup; } priv.params[DH_P] = _gnutls_mpi_copy(dh_params->params[0]); priv.params[DH_G] = _gnutls_mpi_copy(dh_params->params[1]); if (_gnutls_mpi_init_scan_nz (&priv.params[DH_X], priv_key->data, priv_key->size) != 0) { ret = gnutls_assert_val(GNUTLS_E_MPI_SCAN_FAILED); goto cleanup; } priv.params_nr = 3; /* include empty q */ priv.algo = GNUTLS_PK_DH; Z->data = NULL; ret = _gnutls_pk_derive(GNUTLS_PK_DH, Z, &priv, &pub); if (ret < 0) { gnutls_assert(); goto cleanup; } ret = 0; cleanup: gnutls_pk_params_clear(&pub); gnutls_pk_params_clear(&priv); return ret; }
/** * 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; }
/*- * _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; }
int _gnutls_gen_dh_common_client_kx_int(gnutls_session_t session, gnutls_buffer_st * data, gnutls_datum_t * pskkey) { int ret; gnutls_pk_params_st peer_pub; gnutls_datum_t tmp_dh_key = {NULL, 0}; gnutls_pk_params_init(&peer_pub); ret = _gnutls_pk_generate_keys(GNUTLS_PK_DH, 0, &session->key.dh_params, 1); if (ret < 0) return gnutls_assert_val(ret); _gnutls_dh_set_secret_bits(session, _gnutls_mpi_get_nbits(session->key.dh_params.params[DH_X])); ret = _gnutls_buffer_append_mpi(data, 16, session->key.dh_params.params[DH_Y], 0); if (ret < 0) { gnutls_assert(); goto error; } peer_pub.params[DH_Y] = session->key.client_Y; /* calculate the key after calculating the message */ ret = _gnutls_pk_derive(GNUTLS_PK_DH, &tmp_dh_key, &session->key.dh_params, &peer_pub); if (ret < 0) { gnutls_assert(); goto error; } if (_gnutls_cipher_suite_get_kx_algo (session->security_parameters.cipher_suite) != GNUTLS_KX_DHE_PSK) { session->key.key.data = tmp_dh_key.data; session->key.key.size = tmp_dh_key.size; } else { /* In DHE_PSK the key is set differently */ ret = _gnutls_set_psk_session_key(session, pskkey, &tmp_dh_key); _gnutls_free_temp_key_datum(&tmp_dh_key); } if (ret < 0) { gnutls_assert(); goto error; } ret = data->length; error: gnutls_pk_params_clear(&session->key.dh_params); return ret; }
int _gnutls_ecdh_generate_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; gnutls_pk_params_init(¶ms); params.flags = curve; params.algo = GNUTLS_PK_EC; x->data = NULL; y->data = NULL; k->data = NULL; ret = _gnutls_pk_generate_keys(GNUTLS_PK_EC, curve, ¶ms); if (ret < 0) { return gnutls_assert_val(ret); } ret = _gnutls_mpi_dprint_lz(params.params[ECC_X], x); if (ret < 0) { gnutls_assert(); goto fail; } ret = _gnutls_mpi_dprint_lz(params.params[ECC_Y], y); if (ret < 0) { gnutls_assert(); goto fail; } ret = _gnutls_mpi_dprint_lz(params.params[ECC_K], k); if (ret < 0) { gnutls_assert(); goto fail; } ret = 0; goto cleanup; fail: gnutls_free(y->data); gnutls_free(x->data); gnutls_free(k->data); cleanup: gnutls_pk_params_clear(¶ms); return ret; }
/** * 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; if (_gnutls_mpi_init_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_init_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_init_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_clear(&key->params); gnutls_pk_params_release(&key->params); return ret; }
int _gnutls_gen_ecdh_common_client_kx_int(gnutls_session_t session, gnutls_buffer_st * data, gnutls_datum_t * psk_key) { int ret; gnutls_datum_t out; int curve = _gnutls_session_ecc_curve_get(session); /* 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) { gnutls_assert(); goto cleanup; } ret = _gnutls_buffer_append_data_prefix(data, 8, out.data, out.size); _gnutls_free_datum(&out); if (ret < 0) { gnutls_assert(); goto cleanup; } /* generate pre-shared key */ ret = calc_ecdh_key(session, psk_key, curve); if (ret < 0) { gnutls_assert(); goto cleanup; } ret = data->length; cleanup: gnutls_pk_params_clear(&session->key.ecdh_params); return ret; }
int _gnutls_dh_generate_key(gnutls_dh_params_t dh_params, gnutls_datum_t *priv_key, gnutls_datum_t *pub_key) { gnutls_pk_params_st params; int ret; gnutls_pk_params_init(¶ms); params.params[DH_P] = _gnutls_mpi_copy(dh_params->params[0]); params.params[DH_G] = _gnutls_mpi_copy(dh_params->params[1]); params.params_nr = 3; /* include empty q */ params.algo = GNUTLS_PK_DH; priv_key->data = NULL; pub_key->data = NULL; ret = _gnutls_pk_generate_keys(GNUTLS_PK_DH, 0, ¶ms); if (ret < 0) { return gnutls_assert_val(ret); } ret = _gnutls_mpi_dprint_lz(params.params[DH_X], priv_key); if (ret < 0) { gnutls_assert(); goto fail; } ret = _gnutls_mpi_dprint_lz(params.params[DH_Y], pub_key); if (ret < 0) { gnutls_assert(); goto fail; } ret = 0; goto cleanup; fail: gnutls_free(pub_key->data); gnutls_free(priv_key->data); cleanup: gnutls_pk_params_clear(¶ms); return ret; }
int _gnutls_proc_ecdh_common_client_kx(gnutls_session_t session, uint8_t * data, size_t _data_size, gnutls_ecc_curve_t curve, gnutls_datum_t * psk_key) { ssize_t data_size = _data_size; int ret, i = 0; int point_size; if (curve == GNUTLS_ECC_CURVE_INVALID) return gnutls_assert_val(GNUTLS_E_ECC_NO_SUPPORTED_CURVES); DECR_LEN(data_size, 1); point_size = data[i]; i += 1; 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) { gnutls_assert(); goto cleanup; } /* generate pre-shared key */ ret = calc_ecdh_key(session, psk_key, curve); if (ret < 0) { gnutls_assert(); goto cleanup; } cleanup: gnutls_pk_params_clear(&session->key.ecdh_params); return ret; }
int _gnutls_proc_dh_common_client_kx(gnutls_session_t session, uint8_t * data, size_t _data_size, bigint_t g, bigint_t p, gnutls_datum_t * psk_key) { uint16_t n_Y; size_t _n_Y; int ret; ssize_t data_size = _data_size; gnutls_datum_t tmp_dh_key = {NULL, 0}; gnutls_pk_params_st peer_pub; gnutls_pk_params_init(&peer_pub); DECR_LEN(data_size, 2); n_Y = _gnutls_read_uint16(&data[0]); _n_Y = n_Y; DECR_LEN(data_size, n_Y); if (data_size != 0) return gnutls_assert_val(GNUTLS_E_UNEXPECTED_PACKET_LENGTH); if (_gnutls_mpi_init_scan_nz(&session->key.client_Y, &data[2], _n_Y)) { gnutls_assert(); return GNUTLS_E_RECEIVED_ILLEGAL_PARAMETER; /* most likely zero or illegal size */ } _gnutls_dh_set_peer_public(session, session->key.client_Y); peer_pub.params[DH_Y] = session->key.client_Y; /* calculate the key after calculating the message */ ret = _gnutls_pk_derive(GNUTLS_PK_DH, &tmp_dh_key, &session->key.dh_params, &peer_pub); if (ret < 0) { gnutls_assert(); goto error; } if (psk_key == NULL) { session->key.key.data = tmp_dh_key.data; session->key.key.size = tmp_dh_key.size; } else { /* In DHE_PSK the key is set differently */ ret = _gnutls_set_psk_session_key(session, psk_key, &tmp_dh_key); _gnutls_free_temp_key_datum(&tmp_dh_key); } if (ret < 0) { gnutls_assert(); goto error; } ret = 0; error: _gnutls_mpi_release(&session->key.client_Y); gnutls_pk_params_clear(&session->key.dh_params); return ret; }
/* Converts an ECC key to * an internal structure (gnutls_private_key) */ int _gnutls_privkey_decode_ecc_key(ASN1_TYPE* pkey_asn, const gnutls_datum_t * raw_key, gnutls_x509_privkey_t pkey, gnutls_ecc_curve_t curve) { int ret; unsigned int version; char oid[MAX_OID_SIZE]; int oid_size; gnutls_datum out; gnutls_pk_params_init(&pkey->params); pkey->params.algo = GNUTLS_PK_EC; if ((ret = asn1_create_element(_gnutls_get_gnutls_asn(), "GNUTLS.ECPrivateKey", pkey_asn)) != ASN1_SUCCESS) { gnutls_assert(); return _gnutls_asn2err(ret); } ret = asn1_der_decoding(pkey_asn, raw_key->data, raw_key->size, NULL); if (ret != ASN1_SUCCESS) { gnutls_assert(); ret = _gnutls_asn2err(ret); 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(); ret = GNUTLS_E_ECC_UNSUPPORTED_CURVE; goto error; } /* read the curve */ if (curve == GNUTLS_ECC_CURVE_INVALID) { oid_size = sizeof(oid); ret = asn1_read_value(*pkey_asn, "parameters.namedCurve", oid, &oid_size); if (ret != ASN1_SUCCESS) { gnutls_assert(); ret = _gnutls_asn2err(ret); 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(); ret = GNUTLS_E_ECC_UNSUPPORTED_CURVE; goto error; } } else { pkey->params.flags = curve; } /* read the public key */ ret = _gnutls_x509_read_value(*pkey_asn, "publicKey", &out); 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_key_int(*pkey_asn, "privateKey", &pkey->params.params[ECC_K]); if (ret < 0) { gnutls_assert(); goto error; } pkey->params.params_nr++; return 0; error: asn1_delete_structure2(pkey_asn, ASN1_DELETE_FLAG_ZEROIZE); gnutls_pk_params_clear(&pkey->params); gnutls_pk_params_release(&pkey->params); return ret; }
/* Encodes the RSA parameters into an ASN.1 RSA private key structure. */ static int _gnutls_asn1_encode_rsa(ASN1_TYPE * c2, gnutls_pk_params_st * params) { int result, ret; uint8_t null = '\0'; gnutls_pk_params_st pk_params; /* we do copy the parameters into a new structure to run _gnutls_pk_fixup, * i.e., regenerate some parameters in case they were broken */ gnutls_pk_params_init(&pk_params); ret = _gnutls_pk_params_copy(&pk_params, params); if (ret < 0) { gnutls_assert(); return ret; } ret = _gnutls_pk_fixup(GNUTLS_PK_RSA, GNUTLS_EXPORT, &pk_params); if (ret < 0) { gnutls_assert(); goto cleanup; } /* Ok. Now we have the data. Create the asn1 structures */ /* first make sure that no previously allocated data are leaked */ if (*c2 != ASN1_TYPE_EMPTY) { asn1_delete_structure(c2); *c2 = ASN1_TYPE_EMPTY; } if ((result = asn1_create_element (_gnutls_get_gnutls_asn(), "GNUTLS.RSAPrivateKey", c2)) != ASN1_SUCCESS) { gnutls_assert(); ret = _gnutls_asn2err(result); goto cleanup; } /* Write PRIME */ ret = _gnutls_x509_write_int(*c2, "modulus", params->params[RSA_MODULUS], 1); if (ret < 0) { gnutls_assert(); goto cleanup; } ret = _gnutls_x509_write_int(*c2, "publicExponent", params->params[RSA_PUB], 1); if (ret < 0) { gnutls_assert(); goto cleanup; } ret = _gnutls_x509_write_key_int(*c2, "privateExponent", params->params[RSA_PRIV], 1); if (ret < 0) { gnutls_assert(); goto cleanup; } ret = _gnutls_x509_write_key_int(*c2, "prime1", params->params[RSA_PRIME1], 1); if (ret < 0) { gnutls_assert(); goto cleanup; } ret = _gnutls_x509_write_key_int(*c2, "prime2", params->params[RSA_PRIME2], 1); if (ret < 0) { gnutls_assert(); goto cleanup; } ret = _gnutls_x509_write_key_int(*c2, "coefficient", params->params[RSA_COEF], 1); if (ret < 0) { gnutls_assert(); goto cleanup; } ret = _gnutls_x509_write_key_int(*c2, "exponent1", params->params[RSA_E1], 1); if (ret < 0) { gnutls_assert(); goto cleanup; } ret = _gnutls_x509_write_key_int(*c2, "exponent2", params->params[RSA_E2], 1); if (ret < 0) { gnutls_assert(); goto cleanup; } if ((result = asn1_write_value(*c2, "otherPrimeInfos", NULL, 0)) != ASN1_SUCCESS) { gnutls_assert(); ret = _gnutls_asn2err(result); goto cleanup; } if ((result = asn1_write_value(*c2, "version", &null, 1)) != ASN1_SUCCESS) { gnutls_assert(); ret = _gnutls_asn2err(result); goto cleanup; } ret = 0; cleanup: if (ret < 0) asn1_delete_structure2(c2, ASN1_DELETE_FLAG_ZEROIZE); gnutls_pk_params_clear(&pk_params); gnutls_pk_params_release(&pk_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; } gnutls_pk_params_init(&pkey->params); pkey->params.algo = GNUTLS_PK_DSA; 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_key_int(dsa_asn, "priv", &pkey->params.params[4])) < 0) { gnutls_assert(); goto error; } pkey->params.params_nr++; return dsa_asn; error: asn1_delete_structure2(&dsa_asn, ASN1_DELETE_FLAG_ZEROIZE); gnutls_pk_params_clear(&pkey->params); gnutls_pk_params_release(&pkey->params); return NULL; }
/** * 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 (optional) * @e1: holds e1 = d mod (p-1) (optional) * @e2: holds e2 = d mod (q-1) (optional) * * 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_init_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_init_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_init_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_init_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_init_scan_nz(&key->params.params[4], q->data, siz)) { gnutls_assert(); ret = GNUTLS_E_MPI_SCAN_FAILED; goto cleanup; } key->params.params_nr++; if (u) { siz = u->size; if (_gnutls_mpi_init_scan_nz(&key->params.params[RSA_COEF], 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_init_scan_nz (&key->params.params[RSA_E1], e1->data, siz)) { gnutls_assert(); ret = GNUTLS_E_MPI_SCAN_FAILED; goto cleanup; } key->params.params_nr++; siz = e2->size; if (_gnutls_mpi_init_scan_nz (&key->params.params[RSA_E2], 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_clear(&key->params); gnutls_pk_params_release(&key->params); return ret; }
/* Extracts DSA and RSA parameters from a certificate. */ int _gnutls_openpgp_privkey_get_mpis(gnutls_openpgp_privkey_t pkey, uint32_t * keyid /*[2] */ , gnutls_pk_params_st * params) { int result; unsigned int i, pk_algorithm; cdk_packet_t pkt; unsigned total; gnutls_pk_params_init(params); if (keyid == NULL) pkt = cdk_kbnode_find_packet(pkey->knode, CDK_PKT_SECRET_KEY); else pkt = _gnutls_openpgp_find_key(pkey->knode, keyid, 1); if (pkt == NULL) { gnutls_assert(); return GNUTLS_E_OPENPGP_GETKEY_FAILED; } pk_algorithm = _gnutls_openpgp_get_algo(pkt->pkt.secret_key->pk->pubkey_algo); switch (pk_algorithm) { case GNUTLS_PK_RSA: /* openpgp does not hold all parameters as in PKCS #1 */ total = RSA_PRIVATE_PARAMS - 2; break; case GNUTLS_PK_DSA: total = DSA_PRIVATE_PARAMS; break; default: gnutls_assert(); return GNUTLS_E_UNSUPPORTED_CERTIFICATE_TYPE; } for (i = 0; i < total; i++) { result = _gnutls_read_pgp_mpi(pkt, 1, i, ¶ms->params[i]); if (result < 0) { gnutls_assert(); goto error; } params->params_nr++; } /* fixup will generate exp1 and exp2 that are not * available here. */ result = _gnutls_pk_fixup(pk_algorithm, GNUTLS_IMPORT, params); if (result < 0) { gnutls_assert(); goto error; } return 0; error: gnutls_pk_params_clear(params); gnutls_pk_params_release(params); return result; }
/* Decodes a GOST privateKey from a PKCS8 structure. */ static int _decode_pkcs8_gost_key(ASN1_TYPE pkcs8_asn, gnutls_x509_privkey_t pkey, gnutls_pk_algorithm_t algo) { int ret; gnutls_datum_t tmp; unsigned char oid[3 * MAX_OID_SIZE]; /* GOST parameters can have 3 OIDs at most */ int len, result; gnutls_pk_params_init(&pkey->params); len = sizeof(oid); result = asn1_read_value(pkcs8_asn, "privateKeyAlgorithm.parameters", oid, &len); if (result != ASN1_SUCCESS) { gnutls_assert(); ret = GNUTLS_E_PARSING_ERROR; goto error; } else { ret = _gnutls_x509_read_gost_params(oid, len, &pkey->params, algo); if (ret < 0) { gnutls_assert(); goto error; } } /* Will be fixed later by pk_fixup */ ret = _gnutls_mpi_init(&pkey->params.params[GOST_X]); if (ret < 0) { gnutls_assert(); goto error; } pkey->params.params_nr++; ret = _gnutls_mpi_init(&pkey->params.params[GOST_Y]); if (ret < 0) { gnutls_assert(); goto error; } pkey->params.params_nr++; _gnutls_mpi_set_ui(pkey->params.params[GOST_X], 0); _gnutls_mpi_set_ui(pkey->params.params[GOST_Y], 0); ret = _gnutls_x509_read_value(pkcs8_asn, "privateKey", &tmp); if (ret < 0) { gnutls_assert(); goto error; } ret = _privkey_decode_gost_key(&tmp, pkey); _gnutls_free_key_datum(&tmp); if (ret < 0) { gnutls_assert(); goto error; } pkey->params.algo = algo; return 0; error: gnutls_pk_params_clear(&pkey->params); gnutls_pk_params_release(&pkey->params); return ret; }
/** * 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_init_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_init_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_init_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_init_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_init_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_clear(&key->params); gnutls_pk_params_release(&key->params); return ret; }
/** * gnutls_openpgp_privkey_sign_hash: * @key: Holds the key * @hash: holds the data to be signed * @signature: will contain newly allocated signature * * 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. * * Deprecated: Use gnutls_privkey_sign_hash() instead. */ int gnutls_openpgp_privkey_sign_hash(gnutls_openpgp_privkey_t key, const gnutls_datum_t * hash, gnutls_datum_t * signature) { int result; 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]; int idx; KEYID_IMPORT(kid, keyid); _gnutls_hard_log("Signing using PGP key ID %s\n", _gnutls_bin2hex(keyid, GNUTLS_OPENPGP_KEYID_SIZE, buf, sizeof(buf), NULL)); idx = gnutls_openpgp_privkey_get_subkey_idx(key, keyid); pk_algorithm = gnutls_openpgp_privkey_get_subkey_pk_algorithm(key, idx, NULL); result = _gnutls_openpgp_privkey_get_mpis(key, kid, ¶ms); } else { _gnutls_hard_log("Signing 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_sign(pk_algorithm, signature, hash, ¶ms); gnutls_pk_params_clear(¶ms); gnutls_pk_params_release(¶ms); if (result < 0) { gnutls_assert(); return result; } return 0; }
int _gnutls_ecdh_compute_key(gnutls_ecc_curve_t curve, const gnutls_datum_t *x, const gnutls_datum_t *y, const gnutls_datum_t *k, const gnutls_datum_t *peer_x, const gnutls_datum_t *peer_y, gnutls_datum_t *Z) { gnutls_pk_params_st pub, priv; int ret; gnutls_pk_params_init(&pub); gnutls_pk_params_init(&priv); pub.algo = GNUTLS_PK_EC; pub.flags = curve; if (_gnutls_mpi_init_scan_nz (&pub.params[ECC_Y], peer_y->data, peer_y->size) != 0) { ret = gnutls_assert_val(GNUTLS_E_MPI_SCAN_FAILED); goto cleanup; } if (_gnutls_mpi_init_scan_nz (&pub.params[ECC_X], peer_x->data, peer_x->size) != 0) { ret = gnutls_assert_val(GNUTLS_E_MPI_SCAN_FAILED); goto cleanup; } pub.params_nr = 2; if (_gnutls_mpi_init_scan_nz (&priv.params[ECC_Y], y->data, y->size) != 0) { ret = gnutls_assert_val(GNUTLS_E_MPI_SCAN_FAILED); goto cleanup; } if (_gnutls_mpi_init_scan_nz (&priv.params[ECC_X], x->data, x->size) != 0) { ret = gnutls_assert_val(GNUTLS_E_MPI_SCAN_FAILED); goto cleanup; } if (_gnutls_mpi_init_scan_nz (&priv.params[ECC_K], k->data, k->size) != 0) { ret = gnutls_assert_val(GNUTLS_E_MPI_SCAN_FAILED); goto cleanup; } priv.params_nr = 3; priv.algo = GNUTLS_PK_EC; priv.flags = curve; Z->data = NULL; ret = _gnutls_pk_derive(GNUTLS_PK_EC, Z, &priv, &pub); if (ret < 0) { gnutls_assert(); goto cleanup; } ret = 0; cleanup: gnutls_pk_params_clear(&pub); gnutls_pk_params_clear(&priv); return ret; }
static int _get_sk_dsa_raw(gnutls_openpgp_privkey_t pkey, gnutls_openpgp_keyid_t keyid, gnutls_datum_t * p, gnutls_datum_t * q, gnutls_datum_t * g, gnutls_datum_t * y, gnutls_datum_t * x) { int pk_algorithm, ret; cdk_packet_t pkt; uint32_t kid32[2]; gnutls_pk_params_st params; if (pkey == NULL) { gnutls_assert(); return GNUTLS_E_INVALID_REQUEST; } KEYID_IMPORT(kid32, keyid); pkt = _gnutls_openpgp_find_key(pkey->knode, kid32, 1); if (pkt == NULL) { gnutls_assert(); return GNUTLS_E_OPENPGP_GETKEY_FAILED; } pk_algorithm = _gnutls_openpgp_get_algo(pkt->pkt.secret_key->pk->pubkey_algo); if (pk_algorithm != GNUTLS_PK_DSA) { gnutls_assert(); return GNUTLS_E_INVALID_REQUEST; } ret = _gnutls_openpgp_privkey_get_mpis(pkey, kid32, ¶ms); if (ret < 0) { gnutls_assert(); return ret; } /* P */ ret = _gnutls_mpi_dprint(params.params[0], p); if (ret < 0) { gnutls_assert(); goto cleanup; } /* Q */ ret = _gnutls_mpi_dprint(params.params[1], q); if (ret < 0) { gnutls_assert(); _gnutls_free_datum(p); goto cleanup; } /* G */ ret = _gnutls_mpi_dprint(params.params[2], g); if (ret < 0) { gnutls_assert(); _gnutls_free_datum(p); _gnutls_free_datum(q); goto cleanup; } /* Y */ ret = _gnutls_mpi_dprint(params.params[3], y); if (ret < 0) { gnutls_assert(); _gnutls_free_datum(p); _gnutls_free_datum(g); _gnutls_free_datum(q); goto cleanup; } ret = _gnutls_mpi_dprint(params.params[4], x); if (ret < 0) { gnutls_assert(); _gnutls_free_datum(y); _gnutls_free_datum(p); _gnutls_free_datum(g); _gnutls_free_datum(q); goto cleanup; } ret = 0; cleanup: gnutls_pk_params_clear(¶ms); gnutls_pk_params_release(¶ms); return ret; }
/* 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); pkey->params.algo = GNUTLS_PK_RSA; 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_key_int(pkey_asn, "privateExponent", &pkey->params.params[2])) < 0) { gnutls_assert(); goto error; } pkey->params.params_nr++; if ((result = _gnutls_x509_read_key_int(pkey_asn, "prime1", &pkey->params.params[3])) < 0) { gnutls_assert(); goto error; } pkey->params.params_nr++; if ((result = _gnutls_x509_read_key_int(pkey_asn, "prime2", &pkey->params.params[4])) < 0) { gnutls_assert(); goto error; } pkey->params.params_nr++; if ((result = _gnutls_x509_read_key_int(pkey_asn, "coefficient", &pkey->params.params[5])) < 0) { gnutls_assert(); goto error; } pkey->params.params_nr++; if ((result = _gnutls_x509_read_key_int(pkey_asn, "exponent1", &pkey->params.params[6])) < 0) { gnutls_assert(); goto error; } pkey->params.params_nr++; if ((result = _gnutls_x509_read_key_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_structure2(&pkey_asn, ASN1_DELETE_FLAG_ZEROIZE); gnutls_pk_params_clear(&pkey->params); gnutls_pk_params_release(&pkey->params); return NULL; }