Use the new asn1_read_node_value()
[gnutls.git] / lib / x509 / mpi.c
blobbaef1ee89fcac9d27ff1c1d34193b21fe17723f8
1 /*
2 * Copyright (C) 2003-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>
32 /* Reads an Integer from the DER encoded data
35 int
36 _gnutls_x509_read_der_int (uint8_t * der, int dersize, bigint_t * out)
38 int result;
39 ASN1_TYPE spk = ASN1_TYPE_EMPTY;
41 /* == INTEGER */
42 if ((result = asn1_create_element
43 (_gnutls_get_gnutls_asn (), "GNUTLS.DSAPublicKey",
44 &spk)) != ASN1_SUCCESS)
46 gnutls_assert ();
47 return _gnutls_asn2err (result);
50 result = asn1_der_decoding (&spk, der, dersize, NULL);
52 if (result != ASN1_SUCCESS)
54 gnutls_assert ();
55 asn1_delete_structure (&spk);
56 return _gnutls_asn2err (result);
59 /* Read Y */
61 if ((result = _gnutls_x509_read_int (spk, "", out)) < 0)
63 gnutls_assert ();
64 asn1_delete_structure (&spk);
65 return _gnutls_asn2err (result);
68 asn1_delete_structure (&spk);
70 return 0;
75 /* Extracts DSA and RSA parameters from a certificate.
77 int
78 _gnutls_get_asn_mpis (ASN1_TYPE asn, const char *root,
79 gnutls_pk_params_st * params)
81 int result;
82 char name[256];
83 gnutls_datum_t tmp = { NULL, 0 };
84 gnutls_pk_algorithm_t pk_algorithm;
86 gnutls_pk_params_init(params);
88 result = _gnutls_x509_get_pk_algorithm (asn, root, NULL);
89 if (result < 0)
91 gnutls_assert ();
92 return result;
95 pk_algorithm = result;
97 /* Read the algorithm's parameters
99 _asnstr_append_name (name, sizeof (name), root, ".subjectPublicKey");
100 result = _gnutls_x509_read_value (asn, name, &tmp, 2);
102 if (result < 0)
104 gnutls_assert ();
105 return result;
108 if ((result =
109 _gnutls_x509_read_pubkey (pk_algorithm, tmp.data, tmp.size, params)) < 0)
111 gnutls_assert ();
112 goto error;
115 /* Now read the parameters
117 _gnutls_free_datum (&tmp);
119 _asnstr_append_name (name, sizeof (name), root,
120 ".algorithm.parameters");
122 /* FIXME: If the parameters are not included in the certificate
123 * then the issuer's parameters should be used. This is not
124 * done yet.
127 if (pk_algorithm != GNUTLS_PK_RSA) /* RSA doesn't use parameters */
129 result = _gnutls_x509_read_value (asn, name, &tmp, 0);
130 if (result < 0)
132 gnutls_assert ();
133 goto error;
136 if ((result =
137 _gnutls_x509_read_pubkey_params (pk_algorithm, tmp.data, tmp.size, params)) < 0)
139 gnutls_assert ();
140 goto error;
144 result = 0;
146 error:
147 _gnutls_free_datum (&tmp);
148 return result;
151 /* Extracts DSA and RSA parameters from a certificate.
154 _gnutls_x509_crt_get_mpis (gnutls_x509_crt_t cert,
155 gnutls_pk_params_st * params)
157 /* Read the algorithm's OID
159 return _gnutls_get_asn_mpis (cert->cert,
160 "tbsCertificate.subjectPublicKeyInfo", params);
163 /* Extracts DSA and RSA parameters from a certificate.
166 _gnutls_x509_crq_get_mpis (gnutls_x509_crq_t cert,
167 gnutls_pk_params_st* params)
169 /* Read the algorithm's OID
171 return _gnutls_get_asn_mpis (cert->crq,
172 "certificationRequestInfo.subjectPKInfo",
173 params);
177 * This function writes and encodes the parameters for DSS or RSA keys.
178 * This is the "signatureAlgorithm" fields.
181 _gnutls_x509_write_sig_params (ASN1_TYPE dst, const char *dst_name,
182 gnutls_pk_algorithm_t pk_algorithm,
183 gnutls_digest_algorithm_t dig)
185 int result;
186 char name[128];
187 const char *pk;
189 _gnutls_str_cpy (name, sizeof (name), dst_name);
190 _gnutls_str_cat (name, sizeof (name), ".algorithm");
192 pk = _gnutls_x509_sign_to_oid (pk_algorithm, dig);
193 if (pk == NULL)
195 gnutls_assert ();
196 _gnutls_debug_log
197 ("Cannot find OID for sign algorithm pk: %d dig: %d\n",
198 (int) pk_algorithm, (int) dig);
199 return GNUTLS_E_INVALID_REQUEST;
202 /* write the OID.
204 result = asn1_write_value (dst, name, pk, 1);
205 if (result != ASN1_SUCCESS)
207 gnutls_assert ();
208 return _gnutls_asn2err (result);
212 _gnutls_str_cpy (name, sizeof (name), dst_name);
213 _gnutls_str_cat (name, sizeof (name), ".parameters");
215 if (pk_algorithm == GNUTLS_PK_RSA)
216 result = asn1_write_value (dst, name, ASN1_NULL, ASN1_NULL_SIZE);
217 else
218 result = asn1_write_value (dst, name, NULL, 0);
220 if (result != ASN1_SUCCESS && result != ASN1_ELEMENT_NOT_FOUND)
222 /* Here we ignore the element not found error, since this
223 * may have been disabled before.
225 gnutls_assert ();
226 return _gnutls_asn2err (result);
229 return 0;
235 /* this function reads a (small) unsigned integer
236 * from asn1 structs. Combines the read and the convertion
237 * steps.
240 _gnutls_x509_read_uint (ASN1_TYPE node, const char *value, unsigned int *ret)
242 int len, result;
243 uint8_t *tmpstr;
245 len = 0;
246 result = asn1_read_value (node, value, NULL, &len);
247 if (result != ASN1_MEM_ERROR)
249 gnutls_assert ();
250 return _gnutls_asn2err (result);
253 tmpstr = gnutls_malloc (len);
254 if (tmpstr == NULL)
256 gnutls_assert ();
257 return GNUTLS_E_MEMORY_ERROR;
260 result = asn1_read_value (node, value, tmpstr, &len);
262 if (result != ASN1_SUCCESS)
264 gnutls_assert ();
265 gnutls_free (tmpstr);
266 return _gnutls_asn2err (result);
269 if (len == 1)
270 *ret = tmpstr[0];
271 else if (len == 2)
272 *ret = _gnutls_read_uint16 (tmpstr);
273 else if (len == 3)
274 *ret = _gnutls_read_uint24 (tmpstr);
275 else if (len == 4)
276 *ret = _gnutls_read_uint32 (tmpstr);
277 else
279 gnutls_assert ();
280 gnutls_free (tmpstr);
281 return GNUTLS_E_INTERNAL_ERROR;
284 gnutls_free (tmpstr);
286 return 0;
289 /* Writes the specified integer into the specified node.
292 _gnutls_x509_write_uint32 (ASN1_TYPE node, const char *value, uint32_t num)
294 uint8_t tmpstr[4];
295 int result;
297 _gnutls_write_uint32 (num, tmpstr);
299 result = asn1_write_value (node, value, tmpstr, 4);
301 if (result != ASN1_SUCCESS)
303 gnutls_assert ();
304 return _gnutls_asn2err (result);
307 return 0;