2 * Copyright (C) 2011-2012 Free Software Foundation, Inc.
3 * Copyright (C) 2013 Red Hat
5 * Author: Nikos Mavrogiannopoulos
7 * This file is part of GnuTLS.
9 * The GnuTLS is free software; you can redistribute it and/or
10 * modify it under the terms of the GNU Lesser General Public License
11 * as published by the Free Software Foundation; either version 2.1 of
12 * the License, or (at your option) any later version.
14 * This library is distributed in the hope that it will be useful, but
15 * WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17 * Lesser General Public License for more details.
19 * You should have received a copy of the GNU Lesser General Public License
20 * along with this program. If not, see <http://www.gnu.org/licenses/>
24 #include <gnutls_int.h>
25 #include <gnutls_errors.h>
26 #include <gnutls_global.h>
28 #include <gnutls_datum.h>
31 #include <gnutls_num.h>
32 #include <gnutls_ecc.h>
34 static int _gnutls_x509_read_rsa_pubkey(uint8_t * der, int dersize,
35 gnutls_pk_params_st * params);
36 static int _gnutls_x509_read_dsa_pubkey(uint8_t * der, int dersize,
37 gnutls_pk_params_st * params);
38 static int _gnutls_x509_read_ecc_pubkey(uint8_t * der, int dersize,
39 gnutls_pk_params_st * params);
42 _gnutls_x509_read_dsa_params(uint8_t * der, int dersize,
43 gnutls_pk_params_st * params);
46 * some x509 certificate parsing functions that relate to MPI parameter
47 * extraction. This reads the BIT STRING subjectPublicKey.
48 * Returns 2 parameters (m,e). It does not set params_nr.
51 _gnutls_x509_read_rsa_pubkey(uint8_t * der, int dersize,
52 gnutls_pk_params_st * params)
55 ASN1_TYPE spk = ASN1_TYPE_EMPTY;
57 if ((result = asn1_create_element
58 (_gnutls_get_gnutls_asn(), "GNUTLS.RSAPublicKey", &spk))
61 return _gnutls_asn2err(result);
64 result = asn1_der_decoding(&spk, der, dersize, NULL);
66 if (result != ASN1_SUCCESS) {
68 asn1_delete_structure(&spk);
69 return _gnutls_asn2err(result);
74 _gnutls_x509_read_int(spk, "modulus",
75 ¶ms->params[0])) < 0) {
77 asn1_delete_structure(&spk);
78 return GNUTLS_E_ASN1_GENERIC_ERROR;
81 if ((result = _gnutls_x509_read_int(spk, "publicExponent",
82 ¶ms->params[1])) < 0) {
84 _gnutls_mpi_release(¶ms->params[0]);
85 asn1_delete_structure(&spk);
86 return GNUTLS_E_ASN1_GENERIC_ERROR;
89 asn1_delete_structure(&spk);
96 * some x509 certificate parsing functions that relate to MPI parameter
97 * extraction. This reads the BIT STRING subjectPublicKey.
98 * Returns 2 parameters (m,e). It does not set params_nr.
101 _gnutls_x509_read_ecc_pubkey(uint8_t * der, int dersize,
102 gnutls_pk_params_st * params)
104 /* RFC5480 defines the public key to be an ECPoint (i.e. OCTET STRING),
105 * Then it says that the OCTET STRING _value_ is converted to BIT STRING.
106 * That means that the value we place there is the raw X9.62 one. */
107 return _gnutls_ecc_ansi_x963_import(der, dersize,
108 ¶ms->params[ECC_X],
109 ¶ms->params[ECC_Y]);
114 * from the certificate (subjectPublicKey BIT STRING).
115 * params[0-2]. It does NOT set params_nr.
118 _gnutls_x509_read_dsa_params(uint8_t * der, int dersize,
119 gnutls_pk_params_st * params)
122 ASN1_TYPE spk = ASN1_TYPE_EMPTY;
124 if ((result = asn1_create_element
125 (_gnutls_get_pkix(), "PKIX1.Dss-Parms",
126 &spk)) != ASN1_SUCCESS) {
128 return _gnutls_asn2err(result);
131 result = asn1_der_decoding(&spk, der, dersize, NULL);
133 if (result != ASN1_SUCCESS) {
135 asn1_delete_structure(&spk);
136 return _gnutls_asn2err(result);
139 /* FIXME: If the parameters are not included in the certificate
140 * then the issuer's parameters should be used. This is not
147 _gnutls_x509_read_int(spk, "p", ¶ms->params[0])) < 0) {
149 asn1_delete_structure(&spk);
150 return GNUTLS_E_ASN1_GENERIC_ERROR;
156 _gnutls_x509_read_int(spk, "q", ¶ms->params[1])) < 0) {
158 asn1_delete_structure(&spk);
159 _gnutls_mpi_release(¶ms->params[0]);
160 return GNUTLS_E_ASN1_GENERIC_ERROR;
166 _gnutls_x509_read_int(spk, "g", ¶ms->params[2])) < 0) {
168 asn1_delete_structure(&spk);
169 _gnutls_mpi_release(¶ms->params[0]);
170 _gnutls_mpi_release(¶ms->params[1]);
171 return GNUTLS_E_ASN1_GENERIC_ERROR;
174 asn1_delete_structure(&spk);
180 /* reads the curve from the certificate.
181 * params[0-4]. It does NOT set params_nr.
184 _gnutls_x509_read_ecc_params(uint8_t * der, int dersize,
185 unsigned int * curve)
188 ASN1_TYPE spk = ASN1_TYPE_EMPTY;
189 char oid[MAX_OID_SIZE];
192 if ((ret = asn1_create_element
193 (_gnutls_get_gnutls_asn(), "GNUTLS.ECParameters",
194 &spk)) != ASN1_SUCCESS) {
196 return _gnutls_asn2err(ret);
199 ret = asn1_der_decoding(&spk, der, dersize, NULL);
201 if (ret != ASN1_SUCCESS) {
203 ret = _gnutls_asn2err(ret);
209 oid_size = sizeof(oid);
210 ret = asn1_read_value(spk, "namedCurve", oid, &oid_size);
211 if (ret != ASN1_SUCCESS) {
213 ret = _gnutls_asn2err(ret);
217 *curve = _gnutls_oid_to_ecc_curve(oid);
218 if (*curve == GNUTLS_ECC_CURVE_INVALID) {
219 _gnutls_debug_log("Curve %s is not supported\n", oid);
221 ret = GNUTLS_E_ECC_UNSUPPORTED_CURVE;
229 asn1_delete_structure(&spk);
235 int _gnutls_x509_read_pubkey(gnutls_pk_algorithm_t algo, uint8_t * der,
236 int dersize, gnutls_pk_params_st * params)
242 ret = _gnutls_x509_read_rsa_pubkey(der, dersize, params);
244 params->params_nr = RSA_PUBLIC_PARAMS;
247 ret = _gnutls_x509_read_dsa_pubkey(der, dersize, params);
249 params->params_nr = DSA_PUBLIC_PARAMS;
252 ret = _gnutls_x509_read_ecc_pubkey(der, dersize, params);
254 params->params_nr = ECC_PUBLIC_PARAMS;
257 ret = gnutls_assert_val(GNUTLS_E_UNIMPLEMENTED_FEATURE);
263 int _gnutls_x509_read_pubkey_params(gnutls_pk_algorithm_t algo,
264 uint8_t * der, int dersize,
265 gnutls_pk_params_st * params)
271 return _gnutls_x509_read_dsa_params(der, dersize, params);
273 return _gnutls_x509_read_ecc_params(der, dersize, ¶ms->flags);
275 return gnutls_assert_val(GNUTLS_E_UNIMPLEMENTED_FEATURE);
280 * from the certificate
281 * only sets params[3]
284 _gnutls_x509_read_dsa_pubkey(uint8_t * der, int dersize,
285 gnutls_pk_params_st * params)
287 /* do not set a number */
288 params->params_nr = 0;
289 return _gnutls_x509_read_der_int(der, dersize, ¶ms->params[3]);