2 * Copyright (C) 2003, 2004, 2005, 2007, 2008, 2009, 2010 Free Software
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
20 * License along with this library; if not, write to the Free Software
21 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
26 #include <gnutls_int.h>
27 #include <gnutls_errors.h>
28 #include <gnutls_global.h>
30 #include <gnutls_datum.h>
33 #include <gnutls_num.h>
36 * some x509 certificate parsing functions that relate to MPI parameter
37 * extraction. This reads the BIT STRING subjectPublicKey.
38 * Returns 2 parameters (m,e).
41 _gnutls_x509_read_rsa_params (opaque * der, int dersize, bigint_t * params)
44 ASN1_TYPE spk = ASN1_TYPE_EMPTY;
46 if ((result = asn1_create_element
47 (_gnutls_get_gnutls_asn (), "GNUTLS.RSAPublicKey", &spk))
51 return _gnutls_asn2err (result);
54 result = asn1_der_decoding (&spk, der, dersize, NULL);
56 if (result != ASN1_SUCCESS)
59 asn1_delete_structure (&spk);
60 return _gnutls_asn2err (result);
64 if ((result = _gnutls_x509_read_int (spk, "modulus", ¶ms[0])) < 0)
67 asn1_delete_structure (&spk);
68 return GNUTLS_E_ASN1_GENERIC_ERROR;
71 if ((result = _gnutls_x509_read_int (spk, "publicExponent",
75 _gnutls_mpi_release (¶ms[0]);
76 asn1_delete_structure (&spk);
77 return GNUTLS_E_ASN1_GENERIC_ERROR;
80 asn1_delete_structure (&spk);
88 * from the certificate (subjectPublicKey BIT STRING).
92 _gnutls_x509_read_dsa_params (opaque * der, int dersize, bigint_t * params)
95 ASN1_TYPE spk = ASN1_TYPE_EMPTY;
97 if ((result = asn1_create_element
98 (_gnutls_get_pkix (), "PKIX1.Dss-Parms", &spk)) != ASN1_SUCCESS)
101 return _gnutls_asn2err (result);
104 result = asn1_der_decoding (&spk, der, dersize, NULL);
106 if (result != ASN1_SUCCESS)
109 asn1_delete_structure (&spk);
110 return _gnutls_asn2err (result);
113 /* FIXME: If the parameters are not included in the certificate
114 * then the issuer's parameters should be used. This is not
120 if ((result = _gnutls_x509_read_int (spk, "p", ¶ms[0])) < 0)
123 asn1_delete_structure (&spk);
124 return GNUTLS_E_ASN1_GENERIC_ERROR;
129 if ((result = _gnutls_x509_read_int (spk, "q", ¶ms[1])) < 0)
132 asn1_delete_structure (&spk);
133 _gnutls_mpi_release (¶ms[0]);
134 return GNUTLS_E_ASN1_GENERIC_ERROR;
139 if ((result = _gnutls_x509_read_int (spk, "g", ¶ms[2])) < 0)
142 asn1_delete_structure (&spk);
143 _gnutls_mpi_release (¶ms[0]);
144 _gnutls_mpi_release (¶ms[1]);
145 return GNUTLS_E_ASN1_GENERIC_ERROR;
148 asn1_delete_structure (&spk);
154 /* Reads an Integer from the DER encoded data
158 _gnutls_x509_read_der_int (opaque * der, int dersize, bigint_t * out)
161 ASN1_TYPE spk = ASN1_TYPE_EMPTY;
164 if ((result = asn1_create_element
165 (_gnutls_get_gnutls_asn (), "GNUTLS.DSAPublicKey",
166 &spk)) != ASN1_SUCCESS)
169 return _gnutls_asn2err (result);
172 result = asn1_der_decoding (&spk, der, dersize, NULL);
174 if (result != ASN1_SUCCESS)
177 asn1_delete_structure (&spk);
178 return _gnutls_asn2err (result);
183 if ((result = _gnutls_x509_read_int (spk, "", out)) < 0)
186 asn1_delete_structure (&spk);
187 return _gnutls_asn2err (result);
190 asn1_delete_structure (&spk);
197 * from the certificate
198 * only sets params[3]
201 _gnutls_x509_read_dsa_pubkey (opaque * der, int dersize, bigint_t * params)
203 return _gnutls_x509_read_der_int (der, dersize, ¶ms[3]);
207 /* Extracts DSA and RSA parameters from a certificate.
210 _gnutls_get_asn_mpis (ASN1_TYPE asn, const char *root,
211 bigint_t * params, int *params_size)
215 gnutls_datum_t tmp = { NULL, 0 };
216 gnutls_pk_algorithm pk_algorithm;
218 result = _gnutls_x509_get_pk_algorithm (asn, root, NULL);
225 pk_algorithm = result;
227 /* Read the algorithm's parameters
229 _asnstr_append_name (name, sizeof (name), root, ".subjectPublicKey");
230 result = _gnutls_x509_read_value (asn, name, &tmp, 2);
238 switch (pk_algorithm)
241 /* params[0] is the modulus,
242 * params[1] is the exponent
244 if (*params_size < RSA_PUBLIC_PARAMS)
247 /* internal error. Increase the bigint_ts in params */
248 result = GNUTLS_E_INTERNAL_ERROR;
253 _gnutls_x509_read_rsa_params (tmp.data, tmp.size, params)) < 0)
258 *params_size = RSA_PUBLIC_PARAMS;
268 if (*params_size < DSA_PUBLIC_PARAMS)
271 /* internal error. Increase the bigint_ts in params */
272 result = GNUTLS_E_INTERNAL_ERROR;
277 _gnutls_x509_read_dsa_pubkey (tmp.data, tmp.size, params)) < 0)
283 /* Now read the parameters
285 _gnutls_free_datum (&tmp);
287 _asnstr_append_name (name, sizeof (name), root,
288 ".algorithm.parameters");
289 result = _gnutls_x509_read_value (asn, name, &tmp, 0);
291 /* FIXME: If the parameters are not included in the certificate
292 * then the issuer's parameters should be used. This is not
303 _gnutls_x509_read_dsa_params (tmp.data, tmp.size, params)) < 0)
308 *params_size = DSA_PUBLIC_PARAMS;
313 /* other types like DH
314 * currently not supported
317 result = GNUTLS_E_X509_CERTIFICATE_ERROR;
324 _gnutls_free_datum (&tmp);
328 /* Extracts DSA and RSA parameters from a certificate.
331 _gnutls_x509_crt_get_mpis (gnutls_x509_crt_t cert,
332 bigint_t * params, int *params_size)
334 /* Read the algorithm's OID
336 return _gnutls_get_asn_mpis (cert->cert,
337 "tbsCertificate.subjectPublicKeyInfo", params,
343 /* Extracts DSA and RSA parameters from a certificate.
346 _gnutls_x509_crq_get_mpis (gnutls_x509_crq_t cert,
347 bigint_t * params, int *params_size)
349 /* Read the algorithm's OID
351 return _gnutls_get_asn_mpis (cert->crq,
352 "certificationRequestInfo.subjectPKInfo",
353 params, params_size);
359 * some x509 certificate functions that relate to MPI parameter
360 * setting. This writes the BIT STRING subjectPublicKey.
361 * Needs 2 parameters (m,e).
363 * Allocates the space used to store the DER data.
366 _gnutls_x509_write_rsa_params (bigint_t * params, int params_size,
367 gnutls_datum_t * der)
370 ASN1_TYPE spk = ASN1_TYPE_EMPTY;
378 result = GNUTLS_E_INVALID_REQUEST;
382 if ((result = asn1_create_element
383 (_gnutls_get_gnutls_asn (), "GNUTLS.RSAPublicKey", &spk))
387 return _gnutls_asn2err (result);
390 result = _gnutls_x509_write_int (spk, "modulus", params[0], 1);
397 result = _gnutls_x509_write_int (spk, "publicExponent", params[1], 1);
404 result = _gnutls_x509_der_encode (spk, "", der, 0);
411 asn1_delete_structure (&spk);
415 asn1_delete_structure (&spk);
421 * This function writes and encodes the parameters for DSS or RSA keys.
422 * This is the "signatureAlgorithm" fields.
425 _gnutls_x509_write_sig_params (ASN1_TYPE dst, const char *dst_name,
426 gnutls_pk_algorithm_t pk_algorithm,
427 gnutls_digest_algorithm_t dig)
433 _gnutls_str_cpy (name, sizeof (name), dst_name);
434 _gnutls_str_cat (name, sizeof (name), ".algorithm");
436 pk = _gnutls_x509_sign_to_oid (pk_algorithm, HASH2MAC (dig));
441 ("Cannot find OID for sign algorithm pk: %d dig: %d\n",
442 (int) pk_algorithm, (int) dig);
443 return GNUTLS_E_INVALID_REQUEST;
448 result = asn1_write_value (dst, name, pk, 1);
449 if (result != ASN1_SUCCESS)
452 return _gnutls_asn2err (result);
456 _gnutls_str_cpy (name, sizeof (name), dst_name);
457 _gnutls_str_cat (name, sizeof (name), ".parameters");
459 if (pk_algorithm == GNUTLS_PK_RSA)
460 result = asn1_write_value (dst, name, ASN1_NULL, ASN1_NULL_SIZE);
462 result = asn1_write_value (dst, name, NULL, 0);
464 if (result != ASN1_SUCCESS && result != ASN1_ELEMENT_NOT_FOUND)
466 /* Here we ignore the element not found error, since this
467 * may have been disabled before.
470 return _gnutls_asn2err (result);
477 * This function writes the parameters for DSS keys.
478 * Needs 3 parameters (p,q,g).
480 * Allocates the space used to store the DER data.
483 _gnutls_x509_write_dsa_params (bigint_t * params, int params_size,
484 gnutls_datum_t * der)
487 ASN1_TYPE spk = ASN1_TYPE_EMPTY;
495 result = GNUTLS_E_INVALID_REQUEST;
499 if ((result = asn1_create_element
500 (_gnutls_get_gnutls_asn (), "GNUTLS.DSAParameters", &spk))
504 return _gnutls_asn2err (result);
507 result = _gnutls_x509_write_int (spk, "p", params[0], 1);
514 result = _gnutls_x509_write_int (spk, "q", params[1], 1);
521 result = _gnutls_x509_write_int (spk, "g", params[2], 1);
528 result = _gnutls_x509_der_encode (spk, "", der, 0);
538 asn1_delete_structure (&spk);
543 * This function writes the public parameters for DSS keys.
544 * Needs 1 parameter (y).
546 * Allocates the space used to store the DER data.
549 _gnutls_x509_write_dsa_public_key (bigint_t * params, int params_size,
550 gnutls_datum_t * der)
553 ASN1_TYPE spk = ASN1_TYPE_EMPTY;
561 result = GNUTLS_E_INVALID_REQUEST;
565 if ((result = asn1_create_element
566 (_gnutls_get_gnutls_asn (), "GNUTLS.DSAPublicKey", &spk))
570 return _gnutls_asn2err (result);
573 result = _gnutls_x509_write_int (spk, "", params[3], 1);
580 result = _gnutls_x509_der_encode (spk, "", der, 0);
590 asn1_delete_structure (&spk);
595 /* this function reads a (small) unsigned integer
596 * from asn1 structs. Combines the read and the convertion
600 _gnutls_x509_read_uint (ASN1_TYPE node, const char *value, unsigned int *ret)
606 result = asn1_read_value (node, value, NULL, &len);
607 if (result != ASN1_MEM_ERROR)
610 return _gnutls_asn2err (result);
613 tmpstr = gnutls_malloc (len);
617 return GNUTLS_E_MEMORY_ERROR;
620 result = asn1_read_value (node, value, tmpstr, &len);
622 if (result != ASN1_SUCCESS)
625 gnutls_free (tmpstr);
626 return _gnutls_asn2err (result);
632 *ret = _gnutls_read_uint16 (tmpstr);
634 *ret = _gnutls_read_uint24 (tmpstr);
636 *ret = _gnutls_read_uint32 (tmpstr);
640 gnutls_free (tmpstr);
641 return GNUTLS_E_INTERNAL_ERROR;
644 gnutls_free (tmpstr);
649 /* Writes the specified integer into the specified node.
652 _gnutls_x509_write_uint32 (ASN1_TYPE node, const char *value, uint32_t num)
657 _gnutls_write_uint32 (num, tmpstr);
659 result = asn1_write_value (node, value, tmpstr, 4);
661 if (result != ASN1_SUCCESS)
664 return _gnutls_asn2err (result);