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>
27 #include <gnutls_datum.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
);
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.
49 _gnutls_x509_read_rsa_pubkey (uint8_t * der
, int dersize
, gnutls_pk_params_st
* params
)
52 ASN1_TYPE spk
= ASN1_TYPE_EMPTY
;
54 if ((result
= asn1_create_element
55 (_gnutls_get_gnutls_asn (), "GNUTLS.RSAPublicKey", &spk
))
59 return _gnutls_asn2err (result
);
62 result
= asn1_der_decoding (&spk
, der
, dersize
, NULL
);
64 if (result
!= ASN1_SUCCESS
)
67 asn1_delete_structure (&spk
);
68 return _gnutls_asn2err (result
);
72 if ((result
= _gnutls_x509_read_int (spk
, "modulus", ¶ms
->params
[0])) < 0)
75 asn1_delete_structure (&spk
);
76 return GNUTLS_E_ASN1_GENERIC_ERROR
;
79 if ((result
= _gnutls_x509_read_int (spk
, "publicExponent",
80 ¶ms
->params
[1])) < 0)
83 _gnutls_mpi_release (¶ms
->params
[0]);
84 asn1_delete_structure (&spk
);
85 return GNUTLS_E_ASN1_GENERIC_ERROR
;
88 asn1_delete_structure (&spk
);
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.
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
, ¶ms
->params
[ECC_X
],
106 ¶ms
->params
[ECC_Y
]);
111 * from the certificate (subjectPublicKey BIT STRING).
112 * params[0-2]. It does NOT set params_nr.
115 _gnutls_x509_read_dsa_params (uint8_t * der
, int dersize
, gnutls_pk_params_st
* params
)
118 ASN1_TYPE spk
= ASN1_TYPE_EMPTY
;
120 if ((result
= asn1_create_element
121 (_gnutls_get_pkix (), "PKIX1.Dss-Parms", &spk
)) != ASN1_SUCCESS
)
124 return _gnutls_asn2err (result
);
127 result
= asn1_der_decoding (&spk
, der
, dersize
, NULL
);
129 if (result
!= ASN1_SUCCESS
)
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
143 if ((result
= _gnutls_x509_read_int (spk
, "p", ¶ms
->params
[0])) < 0)
146 asn1_delete_structure (&spk
);
147 return GNUTLS_E_ASN1_GENERIC_ERROR
;
152 if ((result
= _gnutls_x509_read_int (spk
, "q", ¶ms
->params
[1])) < 0)
155 asn1_delete_structure (&spk
);
156 _gnutls_mpi_release (¶ms
->params
[0]);
157 return GNUTLS_E_ASN1_GENERIC_ERROR
;
162 if ((result
= _gnutls_x509_read_int (spk
, "g", ¶ms
->params
[2])) < 0)
165 asn1_delete_structure (&spk
);
166 _gnutls_mpi_release (¶ms
->params
[0]);
167 _gnutls_mpi_release (¶ms
->params
[1]);
168 return GNUTLS_E_ASN1_GENERIC_ERROR
;
171 asn1_delete_structure (&spk
);
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
)
184 ASN1_TYPE spk
= ASN1_TYPE_EMPTY
;
185 char oid
[MAX_OID_SIZE
];
188 if ((ret
= asn1_create_element
189 (_gnutls_get_gnutls_asn (), "GNUTLS.ECParameters", &spk
)) != ASN1_SUCCESS
)
192 return _gnutls_asn2err (ret
);
195 ret
= asn1_der_decoding (&spk
, der
, dersize
, NULL
);
197 if (ret
!= ASN1_SUCCESS
)
200 ret
= _gnutls_asn2err (ret
);
206 oid_size
= sizeof(oid
);
207 ret
= asn1_read_value(spk
, "namedCurve", oid
, &oid_size
);
208 if (ret
!= ASN1_SUCCESS
)
211 ret
= _gnutls_asn2err (ret
);
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
);
220 ret
= GNUTLS_E_ECC_UNSUPPORTED_CURVE
;
224 ret
= _gnutls_ecc_curve_fill_params(params
->flags
, params
);
235 asn1_delete_structure (&spk
);
241 int _gnutls_x509_read_pubkey (gnutls_pk_algorithm_t algo
, uint8_t * der
, int dersize
,
242 gnutls_pk_params_st
* params
)
249 ret
= _gnutls_x509_read_rsa_pubkey(der
, dersize
, params
);
250 if (ret
>= 0) params
->params_nr
= RSA_PUBLIC_PARAMS
;
253 ret
= _gnutls_x509_read_dsa_pubkey(der
, dersize
, params
);
254 if (ret
>= 0) params
->params_nr
= DSA_PUBLIC_PARAMS
;
257 ret
= _gnutls_x509_read_ecc_pubkey(der
, dersize
, params
);
258 if (ret
>= 0) params
->params_nr
= ECC_PUBLIC_PARAMS
;
261 ret
= gnutls_assert_val(GNUTLS_E_UNIMPLEMENTED_FEATURE
);
267 int _gnutls_x509_read_pubkey_params (gnutls_pk_algorithm_t algo
, uint8_t * der
, int dersize
,
268 gnutls_pk_params_st
* params
)
275 return _gnutls_x509_read_dsa_params(der
, dersize
, params
);
277 return _gnutls_x509_read_ecc_params(der
, dersize
, params
);
279 return gnutls_assert_val(GNUTLS_E_UNIMPLEMENTED_FEATURE
);
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
, ¶ms
->params
[3]);