2 * Copyright (C) 2001 Nikos Mavroyanopoulos
4 * This file is part of GNUTLS.
6 * The GNUTLS library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2.1 of the License, or (at your option) any later version.
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with this library; if not, write to the Free Software
18 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
23 #include <gnutls_int.h>
24 #include <gnutls_errors.h>
26 #include <auth_cert.h>
27 #include <gnutls_cert.h>
28 #include <x509_asn1.h>
30 #include <gnutls_datum.h>
31 #include <gnutls_mpi.h>
32 #include <gnutls_global.h>
34 void _gcry_mpi_invm( MPI x
, MPI a
, MPI n
);
36 /* Converts an RSA PKCS#1 key to
37 * an internal structure (gnutls_private_key)
39 int _gnutls_PKCS1key2gnutlsKey(gnutls_private_key
* pkey
,
43 opaque str
[MAX_PARAMETER_SIZE
];
46 pkey
->pk_algorithm
= GNUTLS_PK_RSA
;
49 asn1_create_structure(_gnutls_get_gnutls_asn(),
50 "GNUTLS.RSAPrivateKey", &pkey_asn
,
51 "rsakey")) != ASN_OK
) {
53 return _gnutls_asn2err(result
);
56 if ((sizeof(pkey
->params
) / sizeof(GNUTLS_MPI
)) < RSA_PRIVATE_PARAMS
) {
58 /* internal error. Increase the GNUTLS_MPIs in params */
59 return GNUTLS_E_INTERNAL_ERROR
;
62 result
= asn1_get_der(pkey_asn
, raw_key
.data
, raw_key
.size
);
63 if (result
!= ASN_OK
) {
65 return _gnutls_asn2err(result
);
68 if ((result
= _gnutls_x509_read_int(pkey_asn
, "rsakey.modulus",
70 &pkey
->params
[0])) < 0) {
72 asn1_delete_structure(pkey_asn
);
77 _gnutls_x509_read_int(pkey_asn
, "rsakey.publicExponent", str
,
79 &pkey
->params
[1])) < 0) {
81 asn1_delete_structure(pkey_asn
);
82 _gnutls_mpi_release(&pkey
->params
[0]);
87 _gnutls_x509_read_int(pkey_asn
, "rsakey.privateExponent", str
,
89 &pkey
->params
[2])) < 0) {
91 _gnutls_mpi_release(&pkey
->params
[0]);
92 _gnutls_mpi_release(&pkey
->params
[1]);
93 asn1_delete_structure(pkey_asn
);
97 if ((result
= _gnutls_x509_read_int(pkey_asn
, "rsakey.prime1",
99 &pkey
->params
[3])) < 0) {
101 _gnutls_mpi_release(&pkey
->params
[0]);
102 _gnutls_mpi_release(&pkey
->params
[1]);
103 _gnutls_mpi_release(&pkey
->params
[2]);
104 asn1_delete_structure(pkey_asn
);
108 if ((result
= _gnutls_x509_read_int(pkey_asn
, "rsakey.prime2",
109 str
, sizeof(str
) - 1,
110 &pkey
->params
[4])) < 0) {
112 _gnutls_mpi_release(&pkey
->params
[0]);
113 _gnutls_mpi_release(&pkey
->params
[1]);
114 _gnutls_mpi_release(&pkey
->params
[2]);
115 _gnutls_mpi_release(&pkey
->params
[3]);
116 asn1_delete_structure(pkey_asn
);
121 /* Calculate the coefficient. This is because the gcrypt
122 * library is uses the p,q in the reverse order.
125 _gnutls_mpi_snew(_gnutls_mpi_get_nbits(pkey
->params
[0]));
127 if (pkey
->params
[5] == NULL
) {
129 return GNUTLS_E_MEMORY_ERROR
;
132 _gnutls_mpi_invm(pkey
->params
[5], pkey
->params
[3], pkey
->params
[4]);
135 if ( (result
=_gnutls_x509_read_int( pkey_asn
, "rsakey.coefficient",
136 str
, sizeof(str
)-1, &pkey
->params
[5])) < 0) {
138 _gnutls_mpi_release( &pkey
->params
[0]);
139 _gnutls_mpi_release( &pkey
->params
[1]);
140 _gnutls_mpi_release( &pkey
->params
[2]);
141 _gnutls_mpi_release( &pkey
->params
[3]);
142 _gnutls_mpi_release( &pkey
->params
[4]);
143 asn1_delete_structure(pkey_asn
);
148 pkey
->params_size
= RSA_PRIVATE_PARAMS
;
150 asn1_delete_structure(pkey_asn
);
152 if (gnutls_set_datum(&pkey
->raw
, raw_key
.data
, raw_key
.size
) < 0) {
153 _gnutls_mpi_release(&pkey
->params
[0]);
154 _gnutls_mpi_release(&pkey
->params
[1]);
155 _gnutls_mpi_release(&pkey
->params
[2]);
156 _gnutls_mpi_release(&pkey
->params
[3]);
157 _gnutls_mpi_release(&pkey
->params
[4]);
158 _gnutls_mpi_release(&pkey
->params
[5]);
160 return GNUTLS_E_MEMORY_ERROR
;
168 int _gnutls_DSAkey2gnutlsKey(gnutls_private_key
* pkey
,
169 gnutls_datum raw_key
)
172 opaque str
[MAX_PARAMETER_SIZE
];
175 pkey
->pk_algorithm
= GNUTLS_PK_DSA
;
178 asn1_create_structure(_gnutls_get_gnutls_asn(),
179 "GNUTLS.DSAPrivateKey", &dsa_asn
,
180 "dsakey")) != ASN_OK
) {
182 return _gnutls_asn2err(result
);
185 if ((sizeof(pkey
->params
) / sizeof(GNUTLS_MPI
)) < DSA_PRIVATE_PARAMS
) {
187 /* internal error. Increase the GNUTLS_MPIs in params */
188 return GNUTLS_E_INTERNAL_ERROR
;
191 result
= asn1_get_der(dsa_asn
, raw_key
.data
, raw_key
.size
);
192 if (result
!= ASN_OK
) {
194 return _gnutls_asn2err(result
);
197 if ((result
= _gnutls_x509_read_int(dsa_asn
, "dsakey.p",
198 str
, sizeof(str
) - 1,
199 &pkey
->params
[0])) < 0) {
201 asn1_delete_structure(dsa_asn
);
205 if ((result
= _gnutls_x509_read_int(dsa_asn
, "dsakey.q",
206 str
, sizeof(str
) - 1,
207 &pkey
->params
[1])) < 0) {
209 asn1_delete_structure(dsa_asn
);
210 _gnutls_mpi_release(&pkey
->params
[0]);
214 if ((result
= _gnutls_x509_read_int(dsa_asn
, "dsakey.g",
215 str
, sizeof(str
) - 1,
216 &pkey
->params
[2])) < 0) {
218 asn1_delete_structure(dsa_asn
);
219 _gnutls_mpi_release(&pkey
->params
[0]);
220 _gnutls_mpi_release(&pkey
->params
[1]);
224 if ((result
= _gnutls_x509_read_int(dsa_asn
, "dsakey.Y",
225 str
, sizeof(str
) - 1,
226 &pkey
->params
[3])) < 0) {
228 asn1_delete_structure(dsa_asn
);
229 _gnutls_mpi_release(&pkey
->params
[0]);
230 _gnutls_mpi_release(&pkey
->params
[1]);
231 _gnutls_mpi_release(&pkey
->params
[2]);
235 if ((result
= _gnutls_x509_read_int(dsa_asn
, "dsakey.priv",
236 str
, sizeof(str
) - 1,
237 &pkey
->params
[4])) < 0) {
239 asn1_delete_structure(dsa_asn
);
240 _gnutls_mpi_release(&pkey
->params
[0]);
241 _gnutls_mpi_release(&pkey
->params
[1]);
242 _gnutls_mpi_release(&pkey
->params
[2]);
243 _gnutls_mpi_release(&pkey
->params
[3]);
246 pkey
->params_size
= DSA_PRIVATE_PARAMS
;
248 asn1_delete_structure(dsa_asn
);
250 if (gnutls_set_datum(&pkey
->raw
, raw_key
.data
, raw_key
.size
) < 0) {
251 _gnutls_mpi_release(&pkey
->params
[0]);
252 _gnutls_mpi_release(&pkey
->params
[1]);
253 _gnutls_mpi_release(&pkey
->params
[2]);
254 _gnutls_mpi_release(&pkey
->params
[3]);
255 _gnutls_mpi_release(&pkey
->params
[4]);
257 return GNUTLS_E_MEMORY_ERROR
;
265 void _gnutls_free_private_key(gnutls_private_key pkey
)
269 for (i
= 0; i
< pkey
.params_size
; i
++) {
270 _gnutls_mpi_release(&pkey
.params
[i
]);
273 gnutls_free_datum(&pkey
.raw
);