/* decodes the Dss-Sig-Value structure */ int _gnutls_decode_ber_rs (const gnutls_datum_t * sig_value, bigint_t * r, bigint_t * s) { ASN1_TYPE sig; int result; if ((result = asn1_create_element (_gnutls_get_gnutls_asn (), "GNUTLS.DSASignatureValue", &sig)) != ASN1_SUCCESS) { gnutls_assert (); return _gnutls_asn2err (result); } result = asn1_der_decoding (&sig, sig_value->data, sig_value->size, NULL); if (result != ASN1_SUCCESS) { gnutls_assert (); asn1_delete_structure (&sig); return _gnutls_asn2err (result); } result = _gnutls_x509_read_int (sig, "r", r); if (result < 0) { gnutls_assert (); asn1_delete_structure (&sig); return result; } result = _gnutls_x509_read_int (sig, "s", s); if (result < 0) { gnutls_assert (); _gnutls_mpi_release (s); asn1_delete_structure (&sig); return result; } asn1_delete_structure (&sig); return 0; }
/* * some x509 certificate parsing functions that relate to MPI parameter * extraction. This reads the BIT STRING subjectPublicKey. * Returns 2 parameters (m,e). */ int _gnutls_x509_read_rsa_params (opaque * der, int dersize, bigint_t * params) { int result; ASN1_TYPE spk = ASN1_TYPE_EMPTY; if ((result = asn1_create_element (_gnutls_get_gnutls_asn (), "GNUTLS.RSAPublicKey", &spk)) != ASN1_SUCCESS) { gnutls_assert (); return _gnutls_asn2err (result); } result = asn1_der_decoding (&spk, der, dersize, NULL); if (result != ASN1_SUCCESS) { gnutls_assert (); asn1_delete_structure (&spk); return _gnutls_asn2err (result); } if ((result = _gnutls_x509_read_int (spk, "modulus", ¶ms[0])) < 0) { gnutls_assert (); asn1_delete_structure (&spk); return GNUTLS_E_ASN1_GENERIC_ERROR; } if ((result = _gnutls_x509_read_int (spk, "publicExponent", ¶ms[1])) < 0) { gnutls_assert (); _gnutls_mpi_release (¶ms[0]); asn1_delete_structure (&spk); return GNUTLS_E_ASN1_GENERIC_ERROR; } asn1_delete_structure (&spk); return 0; }
int _gnutls_x509_read_der_int (opaque * der, int dersize, bigint_t * out) { int result; ASN1_TYPE spk = ASN1_TYPE_EMPTY; /* == INTEGER */ if ((result = asn1_create_element (_gnutls_get_gnutls_asn (), "GNUTLS.DSAPublicKey", &spk)) != ASN1_SUCCESS) { gnutls_assert (); return _gnutls_asn2err (result); } result = asn1_der_decoding (&spk, der, dersize, NULL); if (result != ASN1_SUCCESS) { gnutls_assert (); asn1_delete_structure (&spk); return _gnutls_asn2err (result); } /* Read Y */ if ((result = _gnutls_x509_read_int (spk, "", out)) < 0) { gnutls_assert (); asn1_delete_structure (&spk); return _gnutls_asn2err (result); } asn1_delete_structure (&spk); return 0; }
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; }
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; } if ((sizeof (pkey->params) / sizeof (mpi_t)) < DSA_PRIVATE_PARAMS) { gnutls_assert (); /* internal error. Increase the mpi_ts in params */ return NULL; } 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[0])) < 0) { gnutls_assert (); goto error; } if ((result = _gnutls_x509_read_int (dsa_asn, "q", &pkey->params[1])) < 0) { gnutls_assert (); goto error; } if ((result = _gnutls_x509_read_int (dsa_asn, "g", &pkey->params[2])) < 0) { gnutls_assert (); goto error; } if ((result = _gnutls_x509_read_int (dsa_asn, "Y", &pkey->params[3])) < 0) { gnutls_assert (); goto error; } if ((result = _gnutls_x509_read_int (dsa_asn, "priv", &pkey->params[4])) < 0) { gnutls_assert (); goto error; } pkey->params_size = 5; return dsa_asn; error: asn1_delete_structure (&dsa_asn); _gnutls_mpi_release (&pkey->params[0]); _gnutls_mpi_release (&pkey->params[1]); _gnutls_mpi_release (&pkey->params[2]); _gnutls_mpi_release (&pkey->params[3]); _gnutls_mpi_release (&pkey->params[4]); 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; if ((result = asn1_create_element (_gnutls_get_gnutls_asn (), "GNUTLS.RSAPrivateKey", &pkey_asn)) != ASN1_SUCCESS) { gnutls_assert (); return NULL; } if ((sizeof (pkey->params) / sizeof (mpi_t)) < RSA_PRIVATE_PARAMS) { gnutls_assert (); /* internal error. Increase the mpi_ts in params */ 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[0])) < 0) { gnutls_assert (); goto error; } if ((result = _gnutls_x509_read_int (pkey_asn, "publicExponent", &pkey->params[1])) < 0) { gnutls_assert (); goto error; } if ((result = _gnutls_x509_read_int (pkey_asn, "privateExponent", &pkey->params[2])) < 0) { gnutls_assert (); goto error; } if ((result = _gnutls_x509_read_int (pkey_asn, "prime1", &pkey->params[3])) < 0) { gnutls_assert (); goto error; } if ((result = _gnutls_x509_read_int (pkey_asn, "prime2", &pkey->params[4])) < 0) { gnutls_assert (); goto error; } #ifdef CALC_COEFF /* Calculate the coefficient. This is because the gcrypt * library is uses the p,q in the reverse order. */ pkey->params[5] = _gnutls_mpi_snew (_gnutls_mpi_get_nbits (pkey->params[0])); if (pkey->params[5] == NULL) { gnutls_assert (); goto error; } _gnutls_mpi_invm (pkey->params[5], pkey->params[3], pkey->params[4]); /* p, q */ #else if ((result = _gnutls_x509_read_int (pkey_asn, "coefficient", &pkey->params[5])) < 0) { gnutls_assert (); goto error; } #endif pkey->params_size = 6; return pkey_asn; error: asn1_delete_structure (&pkey_asn); _gnutls_mpi_release (&pkey->params[0]); _gnutls_mpi_release (&pkey->params[1]); _gnutls_mpi_release (&pkey->params[2]); _gnutls_mpi_release (&pkey->params[3]); _gnutls_mpi_release (&pkey->params[4]); _gnutls_mpi_release (&pkey->params[5]); return NULL; }
/* reads p,q and g * from the certificate (subjectPublicKey BIT STRING). * params[0-2] */ int _gnutls_x509_read_dsa_params (opaque * der, int dersize, bigint_t * params) { int result; ASN1_TYPE spk = ASN1_TYPE_EMPTY; if ((result = asn1_create_element (_gnutls_get_pkix (), "PKIX1.Dss-Parms", &spk)) != ASN1_SUCCESS) { gnutls_assert (); return _gnutls_asn2err (result); } result = asn1_der_decoding (&spk, der, dersize, NULL); if (result != ASN1_SUCCESS) { gnutls_assert (); asn1_delete_structure (&spk); return _gnutls_asn2err (result); } /* FIXME: If the parameters are not included in the certificate * then the issuer's parameters should be used. This is not * done yet. */ /* Read p */ if ((result = _gnutls_x509_read_int (spk, "p", ¶ms[0])) < 0) { gnutls_assert (); asn1_delete_structure (&spk); return GNUTLS_E_ASN1_GENERIC_ERROR; } /* Read q */ if ((result = _gnutls_x509_read_int (spk, "q", ¶ms[1])) < 0) { gnutls_assert (); asn1_delete_structure (&spk); _gnutls_mpi_release (¶ms[0]); return GNUTLS_E_ASN1_GENERIC_ERROR; } /* Read g */ if ((result = _gnutls_x509_read_int (spk, "g", ¶ms[2])) < 0) { gnutls_assert (); asn1_delete_structure (&spk); _gnutls_mpi_release (¶ms[0]); _gnutls_mpi_release (¶ms[1]); return GNUTLS_E_ASN1_GENERIC_ERROR; } asn1_delete_structure (&spk); return 0; }
/** * gnutls_dh_params_import_pkcs3 - import DH params from a pkcs3 structure * @params: A structure where the parameters will be copied to * @pkcs3_params: should contain a PKCS3 DHParams structure PEM or DER encoded * @format: the format of params. PEM or DER. * * This function will extract the DHParams found in a PKCS3 formatted * structure. This is the format generated by "openssl dhparam" tool. * * If the structure is PEM encoded, it should have a header * of "BEGIN DH PARAMETERS". * * Returns: On success, %GNUTLS_E_SUCCESS (zero) is returned, * otherwise an error code is returned. **/ int gnutls_dh_params_import_pkcs3 (gnutls_dh_params_t params, const gnutls_datum_t * pkcs3_params, gnutls_x509_crt_fmt_t format) { ASN1_TYPE c2; int result, need_free = 0; gnutls_datum_t _params; if (format == GNUTLS_X509_FMT_PEM) { opaque *out; result = _gnutls_fbase64_decode ("DH PARAMETERS", pkcs3_params->data, pkcs3_params->size, &out); if (result <= 0) { if (result == 0) result = GNUTLS_E_INTERNAL_ERROR; gnutls_assert (); return result; } _params.data = out; _params.size = result; need_free = 1; } else { _params.data = pkcs3_params->data; _params.size = pkcs3_params->size; } if ((result = asn1_create_element (_gnutls_get_gnutls_asn (), "GNUTLS.DHParameter", &c2)) != ASN1_SUCCESS) { gnutls_assert (); if (need_free != 0) { gnutls_free (_params.data); _params.data = NULL; } return _gnutls_asn2err (result); } result = asn1_der_decoding (&c2, _params.data, _params.size, NULL); if (need_free != 0) { gnutls_free (_params.data); _params.data = NULL; } if (result != ASN1_SUCCESS) { /* couldn't decode DER */ _gnutls_x509_log ("DHParams: Decoding error %d\n", result); gnutls_assert (); asn1_delete_structure (&c2); return _gnutls_asn2err (result); } /* Read PRIME */ result = _gnutls_x509_read_int (c2, "prime", ¶ms->params[0]); if (result < 0) { asn1_delete_structure (&c2); gnutls_assert (); return result; } /* read the generator */ result = _gnutls_x509_read_int (c2, "base", ¶ms->params[1]); if (result < 0) { asn1_delete_structure (&c2); _gnutls_mpi_release (¶ms->params[0]); gnutls_assert (); return result; } asn1_delete_structure (&c2); return 0; }
/** * gnutls_dh_params_import_pkcs3: * @params: The parameters * @pkcs3_params: should contain a PKCS3 DHParams structure PEM or DER encoded * @format: the format of params. PEM or DER. * * This function will extract the DHParams found in a PKCS3 formatted * structure. This is the format generated by "openssl dhparam" tool. * * If the structure is PEM encoded, it should have a header * of "BEGIN DH PARAMETERS". * * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, * otherwise a negative error code is returned. **/ int gnutls_dh_params_import_pkcs3(gnutls_dh_params_t params, const gnutls_datum_t * pkcs3_params, gnutls_x509_crt_fmt_t format) { ASN1_TYPE c2; int result, need_free = 0; unsigned int q_bits; gnutls_datum_t _params; if (format == GNUTLS_X509_FMT_PEM) { result = _gnutls_fbase64_decode("DH PARAMETERS", pkcs3_params->data, pkcs3_params->size, &_params); if (result < 0) { gnutls_assert(); return result; } need_free = 1; } else { _params.data = pkcs3_params->data; _params.size = pkcs3_params->size; } if ((result = asn1_create_element (_gnutls_get_gnutls_asn(), "GNUTLS.DHParameter", &c2)) != ASN1_SUCCESS) { gnutls_assert(); if (need_free != 0) { gnutls_free(_params.data); _params.data = NULL; } return _gnutls_asn2err(result); } /* PKCS#3 doesn't specify whether DHParameter is encoded as * BER or DER, thus we don't restrict libtasn1 to DER subset */ result = asn1_der_decoding(&c2, _params.data, _params.size, NULL); if (need_free != 0) { gnutls_free(_params.data); _params.data = NULL; } if (result != ASN1_SUCCESS) { /* couldn't decode DER */ _gnutls_debug_log("DHParams: Decoding error %d\n", result); gnutls_assert(); asn1_delete_structure(&c2); return _gnutls_asn2err(result); } /* Read q length */ result = _gnutls_x509_read_uint(c2, "privateValueLength", &q_bits); if (result < 0) { gnutls_assert(); params->q_bits = 0; } else params->q_bits = q_bits; /* Read PRIME */ result = _gnutls_x509_read_int(c2, "prime", ¶ms->params[0]); if (result < 0) { asn1_delete_structure(&c2); gnutls_assert(); return result; } if (_gnutls_mpi_cmp_ui(params->params[0], 0) == 0) { asn1_delete_structure(&c2); return gnutls_assert_val(GNUTLS_E_RECEIVED_ILLEGAL_PARAMETER); } /* read the generator */ result = _gnutls_x509_read_int(c2, "base", ¶ms->params[1]); if (result < 0) { asn1_delete_structure(&c2); _gnutls_mpi_release(¶ms->params[0]); gnutls_assert(); return result; } if (_gnutls_mpi_cmp_ui(params->params[1], 0) == 0) { asn1_delete_structure(&c2); _gnutls_mpi_release(¶ms->params[0]); return gnutls_assert_val(GNUTLS_E_RECEIVED_ILLEGAL_PARAMETER); } asn1_delete_structure(&c2); return 0; }