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>
27 #include <gnutls_datum.h>
30 #include <gnutls_num.h>
32 /* Reads an Integer from the DER encoded data
36 _gnutls_x509_read_der_int (uint8_t * der
, int dersize
, bigint_t
* out
)
39 ASN1_TYPE spk
= ASN1_TYPE_EMPTY
;
42 if ((result
= asn1_create_element
43 (_gnutls_get_gnutls_asn (), "GNUTLS.DSAPublicKey",
44 &spk
)) != ASN1_SUCCESS
)
47 return _gnutls_asn2err (result
);
50 result
= asn1_der_decoding (&spk
, der
, dersize
, NULL
);
52 if (result
!= ASN1_SUCCESS
)
55 asn1_delete_structure (&spk
);
56 return _gnutls_asn2err (result
);
61 if ((result
= _gnutls_x509_read_int (spk
, "", out
)) < 0)
64 asn1_delete_structure (&spk
);
65 return _gnutls_asn2err (result
);
68 asn1_delete_structure (&spk
);
75 /* Extracts DSA and RSA parameters from a certificate.
78 _gnutls_get_asn_mpis (ASN1_TYPE asn
, const char *root
,
79 gnutls_pk_params_st
* params
)
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
);
95 pk_algorithm
= result
;
97 /* Read the algorithm's parameters
99 _asnstr_append_name (name
, sizeof (name
), root
, ".subjectPublicKey");
100 result
= _gnutls_x509_read_string (asn
, name
, &tmp
, RV_BIT_STRING
);
109 _gnutls_x509_read_pubkey (pk_algorithm
, tmp
.data
, tmp
.size
, params
)) < 0)
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
127 if (pk_algorithm
!= GNUTLS_PK_RSA
) /* RSA doesn't use parameters */
129 result
= _gnutls_x509_read_value (asn
, name
, &tmp
);
137 _gnutls_x509_read_pubkey_params (pk_algorithm
, tmp
.data
, tmp
.size
, params
)) < 0)
147 _gnutls_free_datum (&tmp
);
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",
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
)
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
);
197 ("Cannot find OID for sign algorithm pk: %d dig: %d\n",
198 (int) pk_algorithm
, (int) dig
);
199 return GNUTLS_E_INVALID_REQUEST
;
204 result
= asn1_write_value (dst
, name
, pk
, 1);
205 if (result
!= ASN1_SUCCESS
)
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
);
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.
226 return _gnutls_asn2err (result
);
232 /* this function reads a (small) unsigned integer
233 * from asn1 structs. Combines the read and the convertion
237 _gnutls_x509_read_uint (ASN1_TYPE node
, const char *value
, unsigned int *ret
)
243 result
= asn1_read_value (node
, value
, NULL
, &len
);
244 if (result
!= ASN1_MEM_ERROR
)
247 return _gnutls_asn2err (result
);
250 tmpstr
= gnutls_malloc (len
);
254 return GNUTLS_E_MEMORY_ERROR
;
257 result
= asn1_read_value (node
, value
, tmpstr
, &len
);
259 if (result
!= ASN1_SUCCESS
)
262 gnutls_free (tmpstr
);
263 return _gnutls_asn2err (result
);
269 *ret
= _gnutls_read_uint16 (tmpstr
);
271 *ret
= _gnutls_read_uint24 (tmpstr
);
273 *ret
= _gnutls_read_uint32 (tmpstr
);
277 gnutls_free (tmpstr
);
278 return GNUTLS_E_INTERNAL_ERROR
;
281 gnutls_free (tmpstr
);
286 /* Writes the specified integer into the specified node.
289 _gnutls_x509_write_uint32 (ASN1_TYPE node
, const char *value
, uint32_t num
)
294 _gnutls_write_uint32 (num
, tmpstr
);
296 result
= asn1_write_value (node
, value
, tmpstr
, 4);
298 if (result
!= ASN1_SUCCESS
)
301 return _gnutls_asn2err (result
);