Details | Last modification | View Log | RSS feed
Rev | Author | Line No. | Line |
---|---|---|---|
8774 | rgimad | 1 | /* |
2 | * Public Key layer for writing key files and structures |
||
3 | * |
||
4 | * Copyright (C) 2006-2015, ARM Limited, All Rights Reserved |
||
5 | * SPDX-License-Identifier: GPL-2.0 |
||
6 | * |
||
7 | * This program is free software; you can redistribute it and/or modify |
||
8 | * it under the terms of the GNU General Public License as published by |
||
9 | * the Free Software Foundation; either version 2 of the License, or |
||
10 | * (at your option) any later version. |
||
11 | * |
||
12 | * This program is distributed in the hope that it will be useful, |
||
13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of |
||
14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
||
15 | * GNU General Public License for more details. |
||
16 | * |
||
17 | * You should have received a copy of the GNU General Public License along |
||
18 | * with this program; if not, write to the Free Software Foundation, Inc., |
||
19 | * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. |
||
20 | * |
||
21 | * This file is part of mbed TLS (https://tls.mbed.org) |
||
22 | */ |
||
23 | |||
24 | #if !defined(MBEDTLS_CONFIG_FILE) |
||
25 | #include "mbedtls/config.h" |
||
26 | #else |
||
27 | #include MBEDTLS_CONFIG_FILE |
||
28 | #endif |
||
29 | |||
30 | #if defined(MBEDTLS_PK_WRITE_C) |
||
31 | |||
32 | #include "mbedtls/pk.h" |
||
33 | #include "mbedtls/asn1write.h" |
||
34 | #include "mbedtls/oid.h" |
||
35 | #include "mbedtls/platform_util.h" |
||
36 | |||
37 | #include |
||
38 | |||
39 | #if defined(MBEDTLS_RSA_C) |
||
40 | #include "mbedtls/rsa.h" |
||
41 | #endif |
||
42 | #if defined(MBEDTLS_ECP_C) |
||
43 | #include "mbedtls/bignum.h" |
||
44 | #include "mbedtls/ecp.h" |
||
45 | #include "mbedtls/platform_util.h" |
||
46 | #endif |
||
47 | #if defined(MBEDTLS_ECDSA_C) |
||
48 | #include "mbedtls/ecdsa.h" |
||
49 | #endif |
||
50 | #if defined(MBEDTLS_PEM_WRITE_C) |
||
51 | #include "mbedtls/pem.h" |
||
52 | #endif |
||
53 | |||
54 | #if defined(MBEDTLS_PLATFORM_C) |
||
55 | #include "mbedtls/platform.h" |
||
56 | #else |
||
57 | #include |
||
58 | #define mbedtls_calloc calloc |
||
59 | #define mbedtls_free free |
||
60 | #endif |
||
61 | |||
62 | /* Parameter validation macros based on platform_util.h */ |
||
63 | #define PK_VALIDATE_RET( cond ) \ |
||
64 | MBEDTLS_INTERNAL_VALIDATE_RET( cond, MBEDTLS_ERR_PK_BAD_INPUT_DATA ) |
||
65 | #define PK_VALIDATE( cond ) \ |
||
66 | MBEDTLS_INTERNAL_VALIDATE( cond ) |
||
67 | |||
68 | #if defined(MBEDTLS_RSA_C) |
||
69 | /* |
||
70 | * RSAPublicKey ::= SEQUENCE { |
||
71 | * modulus INTEGER, -- n |
||
72 | * publicExponent INTEGER -- e |
||
73 | * } |
||
74 | */ |
||
75 | static int pk_write_rsa_pubkey( unsigned char **p, unsigned char *start, |
||
76 | mbedtls_rsa_context *rsa ) |
||
77 | { |
||
78 | int ret; |
||
79 | size_t len = 0; |
||
80 | mbedtls_mpi T; |
||
81 | |||
82 | mbedtls_mpi_init( &T ); |
||
83 | |||
84 | /* Export E */ |
||
85 | if ( ( ret = mbedtls_rsa_export( rsa, NULL, NULL, NULL, NULL, &T ) ) != 0 || |
||
86 | ( ret = mbedtls_asn1_write_mpi( p, start, &T ) ) < 0 ) |
||
87 | goto end_of_export; |
||
88 | len += ret; |
||
89 | |||
90 | /* Export N */ |
||
91 | if ( ( ret = mbedtls_rsa_export( rsa, &T, NULL, NULL, NULL, NULL ) ) != 0 || |
||
92 | ( ret = mbedtls_asn1_write_mpi( p, start, &T ) ) < 0 ) |
||
93 | goto end_of_export; |
||
94 | len += ret; |
||
95 | |||
96 | end_of_export: |
||
97 | |||
98 | mbedtls_mpi_free( &T ); |
||
99 | if( ret < 0 ) |
||
100 | return( ret ); |
||
101 | |||
102 | MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_len( p, start, len ) ); |
||
103 | MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_tag( p, start, MBEDTLS_ASN1_CONSTRUCTED | |
||
104 | MBEDTLS_ASN1_SEQUENCE ) ); |
||
105 | |||
106 | return( (int) len ); |
||
107 | } |
||
108 | #endif /* MBEDTLS_RSA_C */ |
||
109 | |||
110 | #if defined(MBEDTLS_ECP_C) |
||
111 | /* |
||
112 | * EC public key is an EC point |
||
113 | */ |
||
114 | static int pk_write_ec_pubkey( unsigned char **p, unsigned char *start, |
||
115 | mbedtls_ecp_keypair *ec ) |
||
116 | { |
||
117 | int ret; |
||
118 | size_t len = 0; |
||
119 | unsigned char buf[MBEDTLS_ECP_MAX_PT_LEN]; |
||
120 | |||
121 | if( ( ret = mbedtls_ecp_point_write_binary( &ec->grp, &ec->Q, |
||
122 | MBEDTLS_ECP_PF_UNCOMPRESSED, |
||
123 | &len, buf, sizeof( buf ) ) ) != 0 ) |
||
124 | { |
||
125 | return( ret ); |
||
126 | } |
||
127 | |||
128 | if( *p < start || (size_t)( *p - start ) < len ) |
||
129 | return( MBEDTLS_ERR_ASN1_BUF_TOO_SMALL ); |
||
130 | |||
131 | *p -= len; |
||
132 | memcpy( *p, buf, len ); |
||
133 | |||
134 | return( (int) len ); |
||
135 | } |
||
136 | |||
137 | /* |
||
138 | * ECParameters ::= CHOICE { |
||
139 | * namedCurve OBJECT IDENTIFIER |
||
140 | * } |
||
141 | */ |
||
142 | static int pk_write_ec_param( unsigned char **p, unsigned char *start, |
||
143 | mbedtls_ecp_keypair *ec ) |
||
144 | { |
||
145 | int ret; |
||
146 | size_t len = 0; |
||
147 | const char *oid; |
||
148 | size_t oid_len; |
||
149 | |||
150 | if( ( ret = mbedtls_oid_get_oid_by_ec_grp( ec->grp.id, &oid, &oid_len ) ) != 0 ) |
||
151 | return( ret ); |
||
152 | |||
153 | MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_oid( p, start, oid, oid_len ) ); |
||
154 | |||
155 | return( (int) len ); |
||
156 | } |
||
157 | |||
158 | /* |
||
159 | * privateKey OCTET STRING -- always of length ceil(log2(n)/8) |
||
160 | */ |
||
161 | static int pk_write_ec_private( unsigned char **p, unsigned char *start, |
||
162 | mbedtls_ecp_keypair *ec ) |
||
163 | { |
||
164 | int ret; |
||
165 | size_t byte_length = ( ec->grp.pbits + 7 ) / 8; |
||
166 | unsigned char tmp[MBEDTLS_ECP_MAX_BYTES]; |
||
167 | |||
168 | ret = mbedtls_mpi_write_binary( &ec->d, tmp, byte_length ); |
||
169 | if( ret != 0 ) |
||
170 | goto exit; |
||
171 | ret = mbedtls_asn1_write_octet_string( p, start, tmp, byte_length ); |
||
172 | |||
173 | exit: |
||
174 | mbedtls_platform_zeroize( tmp, byte_length ); |
||
175 | return( ret ); |
||
176 | } |
||
177 | #endif /* MBEDTLS_ECP_C */ |
||
178 | |||
179 | int mbedtls_pk_write_pubkey( unsigned char **p, unsigned char *start, |
||
180 | const mbedtls_pk_context *key ) |
||
181 | { |
||
182 | int ret; |
||
183 | size_t len = 0; |
||
184 | |||
185 | PK_VALIDATE_RET( p != NULL ); |
||
186 | PK_VALIDATE_RET( *p != NULL ); |
||
187 | PK_VALIDATE_RET( start != NULL ); |
||
188 | PK_VALIDATE_RET( key != NULL ); |
||
189 | |||
190 | #if defined(MBEDTLS_RSA_C) |
||
191 | if( mbedtls_pk_get_type( key ) == MBEDTLS_PK_RSA ) |
||
192 | MBEDTLS_ASN1_CHK_ADD( len, pk_write_rsa_pubkey( p, start, mbedtls_pk_rsa( *key ) ) ); |
||
193 | else |
||
194 | #endif |
||
195 | #if defined(MBEDTLS_ECP_C) |
||
196 | if( mbedtls_pk_get_type( key ) == MBEDTLS_PK_ECKEY ) |
||
197 | MBEDTLS_ASN1_CHK_ADD( len, pk_write_ec_pubkey( p, start, mbedtls_pk_ec( *key ) ) ); |
||
198 | else |
||
199 | #endif |
||
200 | return( MBEDTLS_ERR_PK_FEATURE_UNAVAILABLE ); |
||
201 | |||
202 | return( (int) len ); |
||
203 | } |
||
204 | |||
205 | int mbedtls_pk_write_pubkey_der( mbedtls_pk_context *key, unsigned char *buf, size_t size ) |
||
206 | { |
||
207 | int ret; |
||
208 | unsigned char *c; |
||
209 | size_t len = 0, par_len = 0, oid_len; |
||
210 | const char *oid; |
||
211 | |||
212 | PK_VALIDATE_RET( key != NULL ); |
||
213 | if( size == 0 ) |
||
214 | return( MBEDTLS_ERR_ASN1_BUF_TOO_SMALL ); |
||
215 | PK_VALIDATE_RET( buf != NULL ); |
||
216 | |||
217 | c = buf + size; |
||
218 | |||
219 | MBEDTLS_ASN1_CHK_ADD( len, mbedtls_pk_write_pubkey( &c, buf, key ) ); |
||
220 | |||
221 | if( c - buf < 1 ) |
||
222 | return( MBEDTLS_ERR_ASN1_BUF_TOO_SMALL ); |
||
223 | |||
224 | /* |
||
225 | * SubjectPublicKeyInfo ::= SEQUENCE { |
||
226 | * algorithm AlgorithmIdentifier, |
||
227 | * subjectPublicKey BIT STRING } |
||
228 | */ |
||
229 | *--c = 0; |
||
230 | len += 1; |
||
231 | |||
232 | MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_len( &c, buf, len ) ); |
||
233 | MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_tag( &c, buf, MBEDTLS_ASN1_BIT_STRING ) ); |
||
234 | |||
235 | if( ( ret = mbedtls_oid_get_oid_by_pk_alg( mbedtls_pk_get_type( key ), |
||
236 | &oid, &oid_len ) ) != 0 ) |
||
237 | { |
||
238 | return( ret ); |
||
239 | } |
||
240 | |||
241 | #if defined(MBEDTLS_ECP_C) |
||
242 | if( mbedtls_pk_get_type( key ) == MBEDTLS_PK_ECKEY ) |
||
243 | { |
||
244 | MBEDTLS_ASN1_CHK_ADD( par_len, pk_write_ec_param( &c, buf, mbedtls_pk_ec( *key ) ) ); |
||
245 | } |
||
246 | #endif |
||
247 | |||
248 | MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_algorithm_identifier( &c, buf, oid, oid_len, |
||
249 | par_len ) ); |
||
250 | |||
251 | MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_len( &c, buf, len ) ); |
||
252 | MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_tag( &c, buf, MBEDTLS_ASN1_CONSTRUCTED | |
||
253 | MBEDTLS_ASN1_SEQUENCE ) ); |
||
254 | |||
255 | return( (int) len ); |
||
256 | } |
||
257 | |||
258 | int mbedtls_pk_write_key_der( mbedtls_pk_context *key, unsigned char *buf, size_t size ) |
||
259 | { |
||
260 | int ret; |
||
261 | unsigned char *c; |
||
262 | size_t len = 0; |
||
263 | |||
264 | PK_VALIDATE_RET( key != NULL ); |
||
265 | if( size == 0 ) |
||
266 | return( MBEDTLS_ERR_ASN1_BUF_TOO_SMALL ); |
||
267 | PK_VALIDATE_RET( buf != NULL ); |
||
268 | |||
269 | c = buf + size; |
||
270 | |||
271 | #if defined(MBEDTLS_RSA_C) |
||
272 | if( mbedtls_pk_get_type( key ) == MBEDTLS_PK_RSA ) |
||
273 | { |
||
274 | mbedtls_mpi T; /* Temporary holding the exported parameters */ |
||
275 | mbedtls_rsa_context *rsa = mbedtls_pk_rsa( *key ); |
||
276 | |||
277 | /* |
||
278 | * Export the parameters one after another to avoid simultaneous copies. |
||
279 | */ |
||
280 | |||
281 | mbedtls_mpi_init( &T ); |
||
282 | |||
283 | /* Export QP */ |
||
284 | if( ( ret = mbedtls_rsa_export_crt( rsa, NULL, NULL, &T ) ) != 0 || |
||
285 | ( ret = mbedtls_asn1_write_mpi( &c, buf, &T ) ) < 0 ) |
||
286 | goto end_of_export; |
||
287 | len += ret; |
||
288 | |||
289 | /* Export DQ */ |
||
290 | if( ( ret = mbedtls_rsa_export_crt( rsa, NULL, &T, NULL ) ) != 0 || |
||
291 | ( ret = mbedtls_asn1_write_mpi( &c, buf, &T ) ) < 0 ) |
||
292 | goto end_of_export; |
||
293 | len += ret; |
||
294 | |||
295 | /* Export DP */ |
||
296 | if( ( ret = mbedtls_rsa_export_crt( rsa, &T, NULL, NULL ) ) != 0 || |
||
297 | ( ret = mbedtls_asn1_write_mpi( &c, buf, &T ) ) < 0 ) |
||
298 | goto end_of_export; |
||
299 | len += ret; |
||
300 | |||
301 | /* Export Q */ |
||
302 | if ( ( ret = mbedtls_rsa_export( rsa, NULL, NULL, |
||
303 | &T, NULL, NULL ) ) != 0 || |
||
304 | ( ret = mbedtls_asn1_write_mpi( &c, buf, &T ) ) < 0 ) |
||
305 | goto end_of_export; |
||
306 | len += ret; |
||
307 | |||
308 | /* Export P */ |
||
309 | if ( ( ret = mbedtls_rsa_export( rsa, NULL, &T, |
||
310 | NULL, NULL, NULL ) ) != 0 || |
||
311 | ( ret = mbedtls_asn1_write_mpi( &c, buf, &T ) ) < 0 ) |
||
312 | goto end_of_export; |
||
313 | len += ret; |
||
314 | |||
315 | /* Export D */ |
||
316 | if ( ( ret = mbedtls_rsa_export( rsa, NULL, NULL, |
||
317 | NULL, &T, NULL ) ) != 0 || |
||
318 | ( ret = mbedtls_asn1_write_mpi( &c, buf, &T ) ) < 0 ) |
||
319 | goto end_of_export; |
||
320 | len += ret; |
||
321 | |||
322 | /* Export E */ |
||
323 | if ( ( ret = mbedtls_rsa_export( rsa, NULL, NULL, |
||
324 | NULL, NULL, &T ) ) != 0 || |
||
325 | ( ret = mbedtls_asn1_write_mpi( &c, buf, &T ) ) < 0 ) |
||
326 | goto end_of_export; |
||
327 | len += ret; |
||
328 | |||
329 | /* Export N */ |
||
330 | if ( ( ret = mbedtls_rsa_export( rsa, &T, NULL, |
||
331 | NULL, NULL, NULL ) ) != 0 || |
||
332 | ( ret = mbedtls_asn1_write_mpi( &c, buf, &T ) ) < 0 ) |
||
333 | goto end_of_export; |
||
334 | len += ret; |
||
335 | |||
336 | end_of_export: |
||
337 | |||
338 | mbedtls_mpi_free( &T ); |
||
339 | if( ret < 0 ) |
||
340 | return( ret ); |
||
341 | |||
342 | MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_int( &c, buf, 0 ) ); |
||
343 | MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_len( &c, buf, len ) ); |
||
344 | MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_tag( &c, |
||
345 | buf, MBEDTLS_ASN1_CONSTRUCTED | |
||
346 | MBEDTLS_ASN1_SEQUENCE ) ); |
||
347 | } |
||
348 | else |
||
349 | #endif /* MBEDTLS_RSA_C */ |
||
350 | #if defined(MBEDTLS_ECP_C) |
||
351 | if( mbedtls_pk_get_type( key ) == MBEDTLS_PK_ECKEY ) |
||
352 | { |
||
353 | mbedtls_ecp_keypair *ec = mbedtls_pk_ec( *key ); |
||
354 | size_t pub_len = 0, par_len = 0; |
||
355 | |||
356 | /* |
||
357 | * RFC 5915, or SEC1 Appendix C.4 |
||
358 | * |
||
359 | * ECPrivateKey ::= SEQUENCE { |
||
360 | * version INTEGER { ecPrivkeyVer1(1) } (ecPrivkeyVer1), |
||
361 | * privateKey OCTET STRING, |
||
362 | * parameters [0] ECParameters {{ NamedCurve }} OPTIONAL, |
||
363 | * publicKey [1] BIT STRING OPTIONAL |
||
364 | * } |
||
365 | */ |
||
366 | |||
367 | /* publicKey */ |
||
368 | MBEDTLS_ASN1_CHK_ADD( pub_len, pk_write_ec_pubkey( &c, buf, ec ) ); |
||
369 | |||
370 | if( c - buf < 1 ) |
||
371 | return( MBEDTLS_ERR_ASN1_BUF_TOO_SMALL ); |
||
372 | *--c = 0; |
||
373 | pub_len += 1; |
||
374 | |||
375 | MBEDTLS_ASN1_CHK_ADD( pub_len, mbedtls_asn1_write_len( &c, buf, pub_len ) ); |
||
376 | MBEDTLS_ASN1_CHK_ADD( pub_len, mbedtls_asn1_write_tag( &c, buf, MBEDTLS_ASN1_BIT_STRING ) ); |
||
377 | |||
378 | MBEDTLS_ASN1_CHK_ADD( pub_len, mbedtls_asn1_write_len( &c, buf, pub_len ) ); |
||
379 | MBEDTLS_ASN1_CHK_ADD( pub_len, mbedtls_asn1_write_tag( &c, buf, |
||
380 | MBEDTLS_ASN1_CONTEXT_SPECIFIC | MBEDTLS_ASN1_CONSTRUCTED | 1 ) ); |
||
381 | len += pub_len; |
||
382 | |||
383 | /* parameters */ |
||
384 | MBEDTLS_ASN1_CHK_ADD( par_len, pk_write_ec_param( &c, buf, ec ) ); |
||
385 | |||
386 | MBEDTLS_ASN1_CHK_ADD( par_len, mbedtls_asn1_write_len( &c, buf, par_len ) ); |
||
387 | MBEDTLS_ASN1_CHK_ADD( par_len, mbedtls_asn1_write_tag( &c, buf, |
||
388 | MBEDTLS_ASN1_CONTEXT_SPECIFIC | MBEDTLS_ASN1_CONSTRUCTED | 0 ) ); |
||
389 | len += par_len; |
||
390 | |||
391 | /* privateKey */ |
||
392 | MBEDTLS_ASN1_CHK_ADD( len, pk_write_ec_private( &c, buf, ec ) ); |
||
393 | |||
394 | /* version */ |
||
395 | MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_int( &c, buf, 1 ) ); |
||
396 | |||
397 | MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_len( &c, buf, len ) ); |
||
398 | MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_tag( &c, buf, MBEDTLS_ASN1_CONSTRUCTED | |
||
399 | MBEDTLS_ASN1_SEQUENCE ) ); |
||
400 | } |
||
401 | else |
||
402 | #endif /* MBEDTLS_ECP_C */ |
||
403 | return( MBEDTLS_ERR_PK_FEATURE_UNAVAILABLE ); |
||
404 | |||
405 | return( (int) len ); |
||
406 | } |
||
407 | |||
408 | #if defined(MBEDTLS_PEM_WRITE_C) |
||
409 | |||
410 | #define PEM_BEGIN_PUBLIC_KEY "-----BEGIN PUBLIC KEY-----\n" |
||
411 | #define PEM_END_PUBLIC_KEY "-----END PUBLIC KEY-----\n" |
||
412 | |||
413 | #define PEM_BEGIN_PRIVATE_KEY_RSA "-----BEGIN RSA PRIVATE KEY-----\n" |
||
414 | #define PEM_END_PRIVATE_KEY_RSA "-----END RSA PRIVATE KEY-----\n" |
||
415 | #define PEM_BEGIN_PRIVATE_KEY_EC "-----BEGIN EC PRIVATE KEY-----\n" |
||
416 | #define PEM_END_PRIVATE_KEY_EC "-----END EC PRIVATE KEY-----\n" |
||
417 | |||
418 | /* |
||
419 | * Max sizes of key per types. Shown as tag + len (+ content). |
||
420 | */ |
||
421 | |||
422 | #if defined(MBEDTLS_RSA_C) |
||
423 | /* |
||
424 | * RSA public keys: |
||
425 | * SubjectPublicKeyInfo ::= SEQUENCE { 1 + 3 |
||
426 | * algorithm AlgorithmIdentifier, 1 + 1 (sequence) |
||
427 | * + 1 + 1 + 9 (rsa oid) |
||
428 | * + 1 + 1 (params null) |
||
429 | * subjectPublicKey BIT STRING } 1 + 3 + (1 + below) |
||
430 | * RSAPublicKey ::= SEQUENCE { 1 + 3 |
||
431 | * modulus INTEGER, -- n 1 + 3 + MPI_MAX + 1 |
||
432 | * publicExponent INTEGER -- e 1 + 3 + MPI_MAX + 1 |
||
433 | * } |
||
434 | */ |
||
435 | #define RSA_PUB_DER_MAX_BYTES 38 + 2 * MBEDTLS_MPI_MAX_SIZE |
||
436 | |||
437 | /* |
||
438 | * RSA private keys: |
||
439 | * RSAPrivateKey ::= SEQUENCE { 1 + 3 |
||
440 | * version Version, 1 + 1 + 1 |
||
441 | * modulus INTEGER, 1 + 3 + MPI_MAX + 1 |
||
442 | * publicExponent INTEGER, 1 + 3 + MPI_MAX + 1 |
||
443 | * privateExponent INTEGER, 1 + 3 + MPI_MAX + 1 |
||
444 | * prime1 INTEGER, 1 + 3 + MPI_MAX / 2 + 1 |
||
445 | * prime2 INTEGER, 1 + 3 + MPI_MAX / 2 + 1 |
||
446 | * exponent1 INTEGER, 1 + 3 + MPI_MAX / 2 + 1 |
||
447 | * exponent2 INTEGER, 1 + 3 + MPI_MAX / 2 + 1 |
||
448 | * coefficient INTEGER, 1 + 3 + MPI_MAX / 2 + 1 |
||
449 | * otherPrimeInfos OtherPrimeInfos OPTIONAL 0 (not supported) |
||
450 | * } |
||
451 | */ |
||
452 | #define MPI_MAX_SIZE_2 MBEDTLS_MPI_MAX_SIZE / 2 + \ |
||
453 | MBEDTLS_MPI_MAX_SIZE % 2 |
||
454 | #define RSA_PRV_DER_MAX_BYTES 47 + 3 * MBEDTLS_MPI_MAX_SIZE \ |
||
455 | + 5 * MPI_MAX_SIZE_2 |
||
456 | |||
457 | #else /* MBEDTLS_RSA_C */ |
||
458 | |||
459 | #define RSA_PUB_DER_MAX_BYTES 0 |
||
460 | #define RSA_PRV_DER_MAX_BYTES 0 |
||
461 | |||
462 | #endif /* MBEDTLS_RSA_C */ |
||
463 | |||
464 | #if defined(MBEDTLS_ECP_C) |
||
465 | /* |
||
466 | * EC public keys: |
||
467 | * SubjectPublicKeyInfo ::= SEQUENCE { 1 + 2 |
||
468 | * algorithm AlgorithmIdentifier, 1 + 1 (sequence) |
||
469 | * + 1 + 1 + 7 (ec oid) |
||
470 | * + 1 + 1 + 9 (namedCurve oid) |
||
471 | * subjectPublicKey BIT STRING 1 + 2 + 1 [1] |
||
472 | * + 1 (point format) [1] |
||
473 | * + 2 * ECP_MAX (coords) [1] |
||
474 | * } |
||
475 | */ |
||
476 | #define ECP_PUB_DER_MAX_BYTES 30 + 2 * MBEDTLS_ECP_MAX_BYTES |
||
477 | |||
478 | /* |
||
479 | * EC private keys: |
||
480 | * ECPrivateKey ::= SEQUENCE { 1 + 2 |
||
481 | * version INTEGER , 1 + 1 + 1 |
||
482 | * privateKey OCTET STRING, 1 + 1 + ECP_MAX |
||
483 | * parameters [0] ECParameters OPTIONAL, 1 + 1 + (1 + 1 + 9) |
||
484 | * publicKey [1] BIT STRING OPTIONAL 1 + 2 + [1] above |
||
485 | * } |
||
486 | */ |
||
487 | #define ECP_PRV_DER_MAX_BYTES 29 + 3 * MBEDTLS_ECP_MAX_BYTES |
||
488 | |||
489 | #else /* MBEDTLS_ECP_C */ |
||
490 | |||
491 | #define ECP_PUB_DER_MAX_BYTES 0 |
||
492 | #define ECP_PRV_DER_MAX_BYTES 0 |
||
493 | |||
494 | #endif /* MBEDTLS_ECP_C */ |
||
495 | |||
496 | #define PUB_DER_MAX_BYTES RSA_PUB_DER_MAX_BYTES > ECP_PUB_DER_MAX_BYTES ? \ |
||
497 | RSA_PUB_DER_MAX_BYTES : ECP_PUB_DER_MAX_BYTES |
||
498 | #define PRV_DER_MAX_BYTES RSA_PRV_DER_MAX_BYTES > ECP_PRV_DER_MAX_BYTES ? \ |
||
499 | RSA_PRV_DER_MAX_BYTES : ECP_PRV_DER_MAX_BYTES |
||
500 | |||
501 | int mbedtls_pk_write_pubkey_pem( mbedtls_pk_context *key, unsigned char *buf, size_t size ) |
||
502 | { |
||
503 | int ret; |
||
504 | unsigned char output_buf[PUB_DER_MAX_BYTES]; |
||
505 | size_t olen = 0; |
||
506 | |||
507 | PK_VALIDATE_RET( key != NULL ); |
||
508 | PK_VALIDATE_RET( buf != NULL || size == 0 ); |
||
509 | |||
510 | if( ( ret = mbedtls_pk_write_pubkey_der( key, output_buf, |
||
511 | sizeof(output_buf) ) ) < 0 ) |
||
512 | { |
||
513 | return( ret ); |
||
514 | } |
||
515 | |||
516 | if( ( ret = mbedtls_pem_write_buffer( PEM_BEGIN_PUBLIC_KEY, PEM_END_PUBLIC_KEY, |
||
517 | output_buf + sizeof(output_buf) - ret, |
||
518 | ret, buf, size, &olen ) ) != 0 ) |
||
519 | { |
||
520 | return( ret ); |
||
521 | } |
||
522 | |||
523 | return( 0 ); |
||
524 | } |
||
525 | |||
526 | int mbedtls_pk_write_key_pem( mbedtls_pk_context *key, unsigned char *buf, size_t size ) |
||
527 | { |
||
528 | int ret; |
||
529 | unsigned char output_buf[PRV_DER_MAX_BYTES]; |
||
530 | const char *begin, *end; |
||
531 | size_t olen = 0; |
||
532 | |||
533 | PK_VALIDATE_RET( key != NULL ); |
||
534 | PK_VALIDATE_RET( buf != NULL || size == 0 ); |
||
535 | |||
536 | if( ( ret = mbedtls_pk_write_key_der( key, output_buf, sizeof(output_buf) ) ) < 0 ) |
||
537 | return( ret ); |
||
538 | |||
539 | #if defined(MBEDTLS_RSA_C) |
||
540 | if( mbedtls_pk_get_type( key ) == MBEDTLS_PK_RSA ) |
||
541 | { |
||
542 | begin = PEM_BEGIN_PRIVATE_KEY_RSA; |
||
543 | end = PEM_END_PRIVATE_KEY_RSA; |
||
544 | } |
||
545 | else |
||
546 | #endif |
||
547 | #if defined(MBEDTLS_ECP_C) |
||
548 | if( mbedtls_pk_get_type( key ) == MBEDTLS_PK_ECKEY ) |
||
549 | { |
||
550 | begin = PEM_BEGIN_PRIVATE_KEY_EC; |
||
551 | end = PEM_END_PRIVATE_KEY_EC; |
||
552 | } |
||
553 | else |
||
554 | #endif |
||
555 | return( MBEDTLS_ERR_PK_FEATURE_UNAVAILABLE ); |
||
556 | |||
557 | if( ( ret = mbedtls_pem_write_buffer( begin, end, |
||
558 | output_buf + sizeof(output_buf) - ret, |
||
559 | ret, buf, size, &olen ) ) != 0 ) |
||
560 | { |
||
561 | return( ret ); |
||
562 | } |
||
563 | |||
564 | return( 0 ); |
||
565 | } |
||
566 | #endif /* MBEDTLS_PEM_WRITE_C */ |
||
567 | |||
568 | #endif /* MBEDTLS_PK_WRITE_C */>>>>>>>>>>>>>>>>>> |