Corrected bugs in record parsing.
[gnutls.git] / lib / x509 / key_decode.c
blobb2ff84077cdc29254a1f0693b615c0d51b2806ec
1 /*
2 * Copyright (C) 2011-2012 Free Software Foundation, Inc.
4 * Author: Nikos Mavrogiannopoulos
6 * This file is part of GnuTLS.
8 * The GnuTLS is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU Lesser General Public License
10 * as published by the Free Software Foundation; either version 3 of
11 * the License, or (at your option) any later version.
13 * This library is distributed in the hope that it will be useful, but
14 * WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 * Lesser General Public License for more details.
18 * You should have received a copy of the GNU Lesser General Public License
19 * along with this program. If not, see <http://www.gnu.org/licenses/>
23 #include <gnutls_int.h>
24 #include <gnutls_errors.h>
25 #include <gnutls_global.h>
26 #include <libtasn1.h>
27 #include <gnutls_datum.h>
28 #include "common.h"
29 #include "x509_int.h"
30 #include <gnutls_num.h>
31 #include <gnutls_ecc.h>
33 static int _gnutls_x509_read_rsa_pubkey (uint8_t * der, int dersize,
34 gnutls_pk_params_st* params);
35 static int _gnutls_x509_read_dsa_pubkey (uint8_t * der, int dersize,
36 gnutls_pk_params_st * params);
37 static int _gnutls_x509_read_ecc_pubkey (uint8_t * der, int dersize,
38 gnutls_pk_params_st * params);
40 static int
41 _gnutls_x509_read_dsa_params (uint8_t * der, int dersize, gnutls_pk_params_st * params);
44 * some x509 certificate parsing functions that relate to MPI parameter
45 * extraction. This reads the BIT STRING subjectPublicKey.
46 * Returns 2 parameters (m,e). It does not set params_nr.
48 int
49 _gnutls_x509_read_rsa_pubkey (uint8_t * der, int dersize, gnutls_pk_params_st * params)
51 int result;
52 ASN1_TYPE spk = ASN1_TYPE_EMPTY;
54 if ((result = asn1_create_element
55 (_gnutls_get_gnutls_asn (), "GNUTLS.RSAPublicKey", &spk))
56 != ASN1_SUCCESS)
58 gnutls_assert ();
59 return _gnutls_asn2err (result);
62 result = asn1_der_decoding (&spk, der, dersize, NULL);
64 if (result != ASN1_SUCCESS)
66 gnutls_assert ();
67 asn1_delete_structure (&spk);
68 return _gnutls_asn2err (result);
72 if ((result = _gnutls_x509_read_int (spk, "modulus", &params->params[0])) < 0)
74 gnutls_assert ();
75 asn1_delete_structure (&spk);
76 return GNUTLS_E_ASN1_GENERIC_ERROR;
79 if ((result = _gnutls_x509_read_int (spk, "publicExponent",
80 &params->params[1])) < 0)
82 gnutls_assert ();
83 _gnutls_mpi_release (&params->params[0]);
84 asn1_delete_structure (&spk);
85 return GNUTLS_E_ASN1_GENERIC_ERROR;
88 asn1_delete_structure (&spk);
90 return 0;
95 * some x509 certificate parsing functions that relate to MPI parameter
96 * extraction. This reads the BIT STRING subjectPublicKey.
97 * Returns 2 parameters (m,e). It does not set params_nr.
99 int
100 _gnutls_x509_read_ecc_pubkey (uint8_t * der, int dersize, gnutls_pk_params_st * params)
102 /* Eventhough RFC5480 defines the public key to be an ECPoint (i.e. OCTET STRING),
103 * it is actually copied in raw there. Why do they use ASN.1 anyway?
105 return _gnutls_ecc_ansi_x963_import (der, dersize, &params->params[ECC_X],
106 &params->params[ECC_Y]);
110 /* reads p,q and g
111 * from the certificate (subjectPublicKey BIT STRING).
112 * params[0-2]. It does NOT set params_nr.
114 static int
115 _gnutls_x509_read_dsa_params (uint8_t * der, int dersize, gnutls_pk_params_st * params)
117 int result;
118 ASN1_TYPE spk = ASN1_TYPE_EMPTY;
120 if ((result = asn1_create_element
121 (_gnutls_get_pkix (), "PKIX1.Dss-Parms", &spk)) != ASN1_SUCCESS)
123 gnutls_assert ();
124 return _gnutls_asn2err (result);
127 result = asn1_der_decoding (&spk, der, dersize, NULL);
129 if (result != ASN1_SUCCESS)
131 gnutls_assert ();
132 asn1_delete_structure (&spk);
133 return _gnutls_asn2err (result);
136 /* FIXME: If the parameters are not included in the certificate
137 * then the issuer's parameters should be used. This is not
138 * done yet.
141 /* Read p */
143 if ((result = _gnutls_x509_read_int (spk, "p", &params->params[0])) < 0)
145 gnutls_assert ();
146 asn1_delete_structure (&spk);
147 return GNUTLS_E_ASN1_GENERIC_ERROR;
150 /* Read q */
152 if ((result = _gnutls_x509_read_int (spk, "q", &params->params[1])) < 0)
154 gnutls_assert ();
155 asn1_delete_structure (&spk);
156 _gnutls_mpi_release (&params->params[0]);
157 return GNUTLS_E_ASN1_GENERIC_ERROR;
160 /* Read g */
162 if ((result = _gnutls_x509_read_int (spk, "g", &params->params[2])) < 0)
164 gnutls_assert ();
165 asn1_delete_structure (&spk);
166 _gnutls_mpi_release (&params->params[0]);
167 _gnutls_mpi_release (&params->params[1]);
168 return GNUTLS_E_ASN1_GENERIC_ERROR;
171 asn1_delete_structure (&spk);
173 return 0;
177 /* reads the curve from the certificate.
178 * params[0-4]. It does NOT set params_nr.
181 _gnutls_x509_read_ecc_params (uint8_t * der, int dersize, gnutls_pk_params_st * params)
183 int ret;
184 ASN1_TYPE spk = ASN1_TYPE_EMPTY;
185 char oid[MAX_OID_SIZE];
186 int oid_size;
188 if ((ret = asn1_create_element
189 (_gnutls_get_gnutls_asn (), "GNUTLS.ECParameters", &spk)) != ASN1_SUCCESS)
191 gnutls_assert ();
192 return _gnutls_asn2err (ret);
195 ret = asn1_der_decoding (&spk, der, dersize, NULL);
197 if (ret != ASN1_SUCCESS)
199 gnutls_assert ();
200 ret = _gnutls_asn2err (ret);
201 goto cleanup;
204 /* Read curve */
205 /* read the curve */
206 oid_size = sizeof(oid);
207 ret = asn1_read_value(spk, "namedCurve", oid, &oid_size);
208 if (ret != ASN1_SUCCESS)
210 gnutls_assert ();
211 ret = _gnutls_asn2err (ret);
212 goto cleanup;
215 params->flags = _gnutls_oid_to_ecc_curve(oid);
216 if (params->flags == GNUTLS_ECC_CURVE_INVALID)
218 _gnutls_debug_log("Curve %s is not supported\n", oid);
219 gnutls_assert();
220 ret = GNUTLS_E_ECC_UNSUPPORTED_CURVE;
221 goto cleanup;
224 ret = _gnutls_ecc_curve_fill_params(params->flags, params);
225 if (ret < 0)
227 gnutls_assert();
228 goto cleanup;
231 ret = 0;
233 cleanup:
235 asn1_delete_structure (&spk);
237 return ret;
241 int _gnutls_x509_read_pubkey (gnutls_pk_algorithm_t algo, uint8_t * der, int dersize,
242 gnutls_pk_params_st * params)
244 int ret;
246 switch(algo)
248 case GNUTLS_PK_RSA:
249 ret = _gnutls_x509_read_rsa_pubkey(der, dersize, params);
250 if (ret >= 0) params->params_nr = RSA_PUBLIC_PARAMS;
251 break;
252 case GNUTLS_PK_DSA:
253 ret = _gnutls_x509_read_dsa_pubkey(der, dersize, params);
254 if (ret >= 0) params->params_nr = DSA_PUBLIC_PARAMS;
255 break;
256 case GNUTLS_PK_EC:
257 ret = _gnutls_x509_read_ecc_pubkey(der, dersize, params);
258 if (ret >= 0) params->params_nr = ECC_PUBLIC_PARAMS;
259 break;
260 default:
261 ret = gnutls_assert_val(GNUTLS_E_UNIMPLEMENTED_FEATURE);
262 break;
264 return ret;
267 int _gnutls_x509_read_pubkey_params (gnutls_pk_algorithm_t algo, uint8_t * der, int dersize,
268 gnutls_pk_params_st * params)
270 switch(algo)
272 case GNUTLS_PK_RSA:
273 return 0;
274 case GNUTLS_PK_DSA:
275 return _gnutls_x509_read_dsa_params(der, dersize, params);
276 case GNUTLS_PK_EC:
277 return _gnutls_x509_read_ecc_params(der, dersize, params);
278 default:
279 return gnutls_assert_val(GNUTLS_E_UNIMPLEMENTED_FEATURE);
283 /* reads DSA's Y
284 * from the certificate
285 * only sets params[3]
288 _gnutls_x509_read_dsa_pubkey (uint8_t * der, int dersize, gnutls_pk_params_st * params)
290 /* do not set a number */
291 params->params_nr = 0;
292 return _gnutls_x509_read_der_int (der, dersize, &params->params[3]);