This Trac instance is not used for development anymore!

We migrated our development workflow to git and Gitea.
To test the future redirection, replace trac by ariadne in the page URL.

source: ps/trunk/build/premake/premake5/contrib/mbedtls/library/pkwrite.c

Last change on this file was 20366, checked in by Itms, 7 years ago

Alpha 12 version of Premake 5, including prebuilt binary for Windows.
Directly taken from https://premake.github.io/.

Refs #3729.

File size: 14.4 KB
Line 
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: Apache-2.0
6 *
7 * Licensed under the Apache License, Version 2.0 (the "License"); you may
8 * not use this file except in compliance with the License.
9 * You may obtain a copy of the License at
10 *
11 * http://www.apache.org/licenses/LICENSE-2.0
12 *
13 * Unless required by applicable law or agreed to in writing, software
14 * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
15 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16 * See the License for the specific language governing permissions and
17 * limitations under the License.
18 *
19 * This file is part of mbed TLS (https://tls.mbed.org)
20 */
21
22#if !defined(MBEDTLS_CONFIG_FILE)
23#include "mbedtls/config.h"
24#else
25#include MBEDTLS_CONFIG_FILE
26#endif
27
28#if defined(MBEDTLS_PK_WRITE_C)
29
30#include "mbedtls/pk.h"
31#include "mbedtls/asn1write.h"
32#include "mbedtls/oid.h"
33
34#include <string.h>
35
36#if defined(MBEDTLS_RSA_C)
37#include "mbedtls/rsa.h"
38#endif
39#if defined(MBEDTLS_ECP_C)
40#include "mbedtls/ecp.h"
41#endif
42#if defined(MBEDTLS_ECDSA_C)
43#include "mbedtls/ecdsa.h"
44#endif
45#if defined(MBEDTLS_PEM_WRITE_C)
46#include "mbedtls/pem.h"
47#endif
48
49#if defined(MBEDTLS_PLATFORM_C)
50#include "mbedtls/platform.h"
51#else
52#include <stdlib.h>
53#define mbedtls_calloc calloc
54#define mbedtls_free free
55#endif
56
57#if defined(MBEDTLS_RSA_C)
58/*
59 * RSAPublicKey ::= SEQUENCE {
60 * modulus INTEGER, -- n
61 * publicExponent INTEGER -- e
62 * }
63 */
64static int pk_write_rsa_pubkey( unsigned char **p, unsigned char *start,
65 mbedtls_rsa_context *rsa )
66{
67 int ret;
68 size_t len = 0;
69
70 MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_mpi( p, start, &rsa->E ) );
71 MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_mpi( p, start, &rsa->N ) );
72
73 MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_len( p, start, len ) );
74 MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_tag( p, start, MBEDTLS_ASN1_CONSTRUCTED |
75 MBEDTLS_ASN1_SEQUENCE ) );
76
77 return( (int) len );
78}
79#endif /* MBEDTLS_RSA_C */
80
81#if defined(MBEDTLS_ECP_C)
82/*
83 * EC public key is an EC point
84 */
85static int pk_write_ec_pubkey( unsigned char **p, unsigned char *start,
86 mbedtls_ecp_keypair *ec )
87{
88 int ret;
89 size_t len = 0;
90 unsigned char buf[MBEDTLS_ECP_MAX_PT_LEN];
91
92 if( ( ret = mbedtls_ecp_point_write_binary( &ec->grp, &ec->Q,
93 MBEDTLS_ECP_PF_UNCOMPRESSED,
94 &len, buf, sizeof( buf ) ) ) != 0 )
95 {
96 return( ret );
97 }
98
99 if( *p < start || (size_t)( *p - start ) < len )
100 return( MBEDTLS_ERR_ASN1_BUF_TOO_SMALL );
101
102 *p -= len;
103 memcpy( *p, buf, len );
104
105 return( (int) len );
106}
107
108/*
109 * ECParameters ::= CHOICE {
110 * namedCurve OBJECT IDENTIFIER
111 * }
112 */
113static int pk_write_ec_param( unsigned char **p, unsigned char *start,
114 mbedtls_ecp_keypair *ec )
115{
116 int ret;
117 size_t len = 0;
118 const char *oid;
119 size_t oid_len;
120
121 if( ( ret = mbedtls_oid_get_oid_by_ec_grp( ec->grp.id, &oid, &oid_len ) ) != 0 )
122 return( ret );
123
124 MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_oid( p, start, oid, oid_len ) );
125
126 return( (int) len );
127}
128#endif /* MBEDTLS_ECP_C */
129
130int mbedtls_pk_write_pubkey( unsigned char **p, unsigned char *start,
131 const mbedtls_pk_context *key )
132{
133 int ret;
134 size_t len = 0;
135
136#if defined(MBEDTLS_RSA_C)
137 if( mbedtls_pk_get_type( key ) == MBEDTLS_PK_RSA )
138 MBEDTLS_ASN1_CHK_ADD( len, pk_write_rsa_pubkey( p, start, mbedtls_pk_rsa( *key ) ) );
139 else
140#endif
141#if defined(MBEDTLS_ECP_C)
142 if( mbedtls_pk_get_type( key ) == MBEDTLS_PK_ECKEY )
143 MBEDTLS_ASN1_CHK_ADD( len, pk_write_ec_pubkey( p, start, mbedtls_pk_ec( *key ) ) );
144 else
145#endif
146 return( MBEDTLS_ERR_PK_FEATURE_UNAVAILABLE );
147
148 return( (int) len );
149}
150
151int mbedtls_pk_write_pubkey_der( mbedtls_pk_context *key, unsigned char *buf, size_t size )
152{
153 int ret;
154 unsigned char *c;
155 size_t len = 0, par_len = 0, oid_len;
156 const char *oid;
157
158 c = buf + size;
159
160 MBEDTLS_ASN1_CHK_ADD( len, mbedtls_pk_write_pubkey( &c, buf, key ) );
161
162 if( c - buf < 1 )
163 return( MBEDTLS_ERR_ASN1_BUF_TOO_SMALL );
164
165 /*
166 * SubjectPublicKeyInfo ::= SEQUENCE {
167 * algorithm AlgorithmIdentifier,
168 * subjectPublicKey BIT STRING }
169 */
170 *--c = 0;
171 len += 1;
172
173 MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_len( &c, buf, len ) );
174 MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_tag( &c, buf, MBEDTLS_ASN1_BIT_STRING ) );
175
176 if( ( ret = mbedtls_oid_get_oid_by_pk_alg( mbedtls_pk_get_type( key ),
177 &oid, &oid_len ) ) != 0 )
178 {
179 return( ret );
180 }
181
182#if defined(MBEDTLS_ECP_C)
183 if( mbedtls_pk_get_type( key ) == MBEDTLS_PK_ECKEY )
184 {
185 MBEDTLS_ASN1_CHK_ADD( par_len, pk_write_ec_param( &c, buf, mbedtls_pk_ec( *key ) ) );
186 }
187#endif
188
189 MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_algorithm_identifier( &c, buf, oid, oid_len,
190 par_len ) );
191
192 MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_len( &c, buf, len ) );
193 MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_tag( &c, buf, MBEDTLS_ASN1_CONSTRUCTED |
194 MBEDTLS_ASN1_SEQUENCE ) );
195
196 return( (int) len );
197}
198
199int mbedtls_pk_write_key_der( mbedtls_pk_context *key, unsigned char *buf, size_t size )
200{
201 int ret;
202 unsigned char *c = buf + size;
203 size_t len = 0;
204
205#if defined(MBEDTLS_RSA_C)
206 if( mbedtls_pk_get_type( key ) == MBEDTLS_PK_RSA )
207 {
208 mbedtls_rsa_context *rsa = mbedtls_pk_rsa( *key );
209
210 MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_mpi( &c, buf, &rsa->QP ) );
211 MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_mpi( &c, buf, &rsa->DQ ) );
212 MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_mpi( &c, buf, &rsa->DP ) );
213 MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_mpi( &c, buf, &rsa->Q ) );
214 MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_mpi( &c, buf, &rsa->P ) );
215 MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_mpi( &c, buf, &rsa->D ) );
216 MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_mpi( &c, buf, &rsa->E ) );
217 MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_mpi( &c, buf, &rsa->N ) );
218 MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_int( &c, buf, 0 ) );
219
220 MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_len( &c, buf, len ) );
221 MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_tag( &c, buf, MBEDTLS_ASN1_CONSTRUCTED |
222 MBEDTLS_ASN1_SEQUENCE ) );
223 }
224 else
225#endif /* MBEDTLS_RSA_C */
226#if defined(MBEDTLS_ECP_C)
227 if( mbedtls_pk_get_type( key ) == MBEDTLS_PK_ECKEY )
228 {
229 mbedtls_ecp_keypair *ec = mbedtls_pk_ec( *key );
230 size_t pub_len = 0, par_len = 0;
231
232 /*
233 * RFC 5915, or SEC1 Appendix C.4
234 *
235 * ECPrivateKey ::= SEQUENCE {
236 * version INTEGER { ecPrivkeyVer1(1) } (ecPrivkeyVer1),
237 * privateKey OCTET STRING,
238 * parameters [0] ECParameters {{ NamedCurve }} OPTIONAL,
239 * publicKey [1] BIT STRING OPTIONAL
240 * }
241 */
242
243 /* publicKey */
244 MBEDTLS_ASN1_CHK_ADD( pub_len, pk_write_ec_pubkey( &c, buf, ec ) );
245
246 if( c - buf < 1 )
247 return( MBEDTLS_ERR_ASN1_BUF_TOO_SMALL );
248 *--c = 0;
249 pub_len += 1;
250
251 MBEDTLS_ASN1_CHK_ADD( pub_len, mbedtls_asn1_write_len( &c, buf, pub_len ) );
252 MBEDTLS_ASN1_CHK_ADD( pub_len, mbedtls_asn1_write_tag( &c, buf, MBEDTLS_ASN1_BIT_STRING ) );
253
254 MBEDTLS_ASN1_CHK_ADD( pub_len, mbedtls_asn1_write_len( &c, buf, pub_len ) );
255 MBEDTLS_ASN1_CHK_ADD( pub_len, mbedtls_asn1_write_tag( &c, buf,
256 MBEDTLS_ASN1_CONTEXT_SPECIFIC | MBEDTLS_ASN1_CONSTRUCTED | 1 ) );
257 len += pub_len;
258
259 /* parameters */
260 MBEDTLS_ASN1_CHK_ADD( par_len, pk_write_ec_param( &c, buf, ec ) );
261
262 MBEDTLS_ASN1_CHK_ADD( par_len, mbedtls_asn1_write_len( &c, buf, par_len ) );
263 MBEDTLS_ASN1_CHK_ADD( par_len, mbedtls_asn1_write_tag( &c, buf,
264 MBEDTLS_ASN1_CONTEXT_SPECIFIC | MBEDTLS_ASN1_CONSTRUCTED | 0 ) );
265 len += par_len;
266
267 /* privateKey: write as MPI then fix tag */
268 MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_mpi( &c, buf, &ec->d ) );
269 *c = MBEDTLS_ASN1_OCTET_STRING;
270
271 /* version */
272 MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_int( &c, buf, 1 ) );
273
274 MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_len( &c, buf, len ) );
275 MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_tag( &c, buf, MBEDTLS_ASN1_CONSTRUCTED |
276 MBEDTLS_ASN1_SEQUENCE ) );
277 }
278 else
279#endif /* MBEDTLS_ECP_C */
280 return( MBEDTLS_ERR_PK_FEATURE_UNAVAILABLE );
281
282 return( (int) len );
283}
284
285#if defined(MBEDTLS_PEM_WRITE_C)
286
287#define PEM_BEGIN_PUBLIC_KEY "-----BEGIN PUBLIC KEY-----\n"
288#define PEM_END_PUBLIC_KEY "-----END PUBLIC KEY-----\n"
289
290#define PEM_BEGIN_PRIVATE_KEY_RSA "-----BEGIN RSA PRIVATE KEY-----\n"
291#define PEM_END_PRIVATE_KEY_RSA "-----END RSA PRIVATE KEY-----\n"
292#define PEM_BEGIN_PRIVATE_KEY_EC "-----BEGIN EC PRIVATE KEY-----\n"
293#define PEM_END_PRIVATE_KEY_EC "-----END EC PRIVATE KEY-----\n"
294
295/*
296 * Max sizes of key per types. Shown as tag + len (+ content).
297 */
298
299#if defined(MBEDTLS_RSA_C)
300/*
301 * RSA public keys:
302 * SubjectPublicKeyInfo ::= SEQUENCE { 1 + 3
303 * algorithm AlgorithmIdentifier, 1 + 1 (sequence)
304 * + 1 + 1 + 9 (rsa oid)
305 * + 1 + 1 (params null)
306 * subjectPublicKey BIT STRING } 1 + 3 + (1 + below)
307 * RSAPublicKey ::= SEQUENCE { 1 + 3
308 * modulus INTEGER, -- n 1 + 3 + MPI_MAX + 1
309 * publicExponent INTEGER -- e 1 + 3 + MPI_MAX + 1
310 * }
311 */
312#define RSA_PUB_DER_MAX_BYTES 38 + 2 * MBEDTLS_MPI_MAX_SIZE
313
314/*
315 * RSA private keys:
316 * RSAPrivateKey ::= SEQUENCE { 1 + 3
317 * version Version, 1 + 1 + 1
318 * modulus INTEGER, 1 + 3 + MPI_MAX + 1
319 * publicExponent INTEGER, 1 + 3 + MPI_MAX + 1
320 * privateExponent INTEGER, 1 + 3 + MPI_MAX + 1
321 * prime1 INTEGER, 1 + 3 + MPI_MAX / 2 + 1
322 * prime2 INTEGER, 1 + 3 + MPI_MAX / 2 + 1
323 * exponent1 INTEGER, 1 + 3 + MPI_MAX / 2 + 1
324 * exponent2 INTEGER, 1 + 3 + MPI_MAX / 2 + 1
325 * coefficient INTEGER, 1 + 3 + MPI_MAX / 2 + 1
326 * otherPrimeInfos OtherPrimeInfos OPTIONAL 0 (not supported)
327 * }
328 */
329#define MPI_MAX_SIZE_2 MBEDTLS_MPI_MAX_SIZE / 2 + \
330 MBEDTLS_MPI_MAX_SIZE % 2
331#define RSA_PRV_DER_MAX_BYTES 47 + 3 * MBEDTLS_MPI_MAX_SIZE \
332 + 5 * MPI_MAX_SIZE_2
333
334#else /* MBEDTLS_RSA_C */
335
336#define RSA_PUB_DER_MAX_BYTES 0
337#define RSA_PRV_DER_MAX_BYTES 0
338
339#endif /* MBEDTLS_RSA_C */
340
341#if defined(MBEDTLS_ECP_C)
342/*
343 * EC public keys:
344 * SubjectPublicKeyInfo ::= SEQUENCE { 1 + 2
345 * algorithm AlgorithmIdentifier, 1 + 1 (sequence)
346 * + 1 + 1 + 7 (ec oid)
347 * + 1 + 1 + 9 (namedCurve oid)
348 * subjectPublicKey BIT STRING 1 + 2 + 1 [1]
349 * + 1 (point format) [1]
350 * + 2 * ECP_MAX (coords) [1]
351 * }
352 */
353#define ECP_PUB_DER_MAX_BYTES 30 + 2 * MBEDTLS_ECP_MAX_BYTES
354
355/*
356 * EC private keys:
357 * ECPrivateKey ::= SEQUENCE { 1 + 2
358 * version INTEGER , 1 + 1 + 1
359 * privateKey OCTET STRING, 1 + 1 + ECP_MAX
360 * parameters [0] ECParameters OPTIONAL, 1 + 1 + (1 + 1 + 9)
361 * publicKey [1] BIT STRING OPTIONAL 1 + 2 + [1] above
362 * }
363 */
364#define ECP_PRV_DER_MAX_BYTES 29 + 3 * MBEDTLS_ECP_MAX_BYTES
365
366#else /* MBEDTLS_ECP_C */
367
368#define ECP_PUB_DER_MAX_BYTES 0
369#define ECP_PRV_DER_MAX_BYTES 0
370
371#endif /* MBEDTLS_ECP_C */
372
373#define PUB_DER_MAX_BYTES RSA_PUB_DER_MAX_BYTES > ECP_PUB_DER_MAX_BYTES ? \
374 RSA_PUB_DER_MAX_BYTES : ECP_PUB_DER_MAX_BYTES
375#define PRV_DER_MAX_BYTES RSA_PRV_DER_MAX_BYTES > ECP_PRV_DER_MAX_BYTES ? \
376 RSA_PRV_DER_MAX_BYTES : ECP_PRV_DER_MAX_BYTES
377
378int mbedtls_pk_write_pubkey_pem( mbedtls_pk_context *key, unsigned char *buf, size_t size )
379{
380 int ret;
381 unsigned char output_buf[PUB_DER_MAX_BYTES];
382 size_t olen = 0;
383
384 if( ( ret = mbedtls_pk_write_pubkey_der( key, output_buf,
385 sizeof(output_buf) ) ) < 0 )
386 {
387 return( ret );
388 }
389
390 if( ( ret = mbedtls_pem_write_buffer( PEM_BEGIN_PUBLIC_KEY, PEM_END_PUBLIC_KEY,
391 output_buf + sizeof(output_buf) - ret,
392 ret, buf, size, &olen ) ) != 0 )
393 {
394 return( ret );
395 }
396
397 return( 0 );
398}
399
400int mbedtls_pk_write_key_pem( mbedtls_pk_context *key, unsigned char *buf, size_t size )
401{
402 int ret;
403 unsigned char output_buf[PRV_DER_MAX_BYTES];
404 const char *begin, *end;
405 size_t olen = 0;
406
407 if( ( ret = mbedtls_pk_write_key_der( key, output_buf, sizeof(output_buf) ) ) < 0 )
408 return( ret );
409
410#if defined(MBEDTLS_RSA_C)
411 if( mbedtls_pk_get_type( key ) == MBEDTLS_PK_RSA )
412 {
413 begin = PEM_BEGIN_PRIVATE_KEY_RSA;
414 end = PEM_END_PRIVATE_KEY_RSA;
415 }
416 else
417#endif
418#if defined(MBEDTLS_ECP_C)
419 if( mbedtls_pk_get_type( key ) == MBEDTLS_PK_ECKEY )
420 {
421 begin = PEM_BEGIN_PRIVATE_KEY_EC;
422 end = PEM_END_PRIVATE_KEY_EC;
423 }
424 else
425#endif
426 return( MBEDTLS_ERR_PK_FEATURE_UNAVAILABLE );
427
428 if( ( ret = mbedtls_pem_write_buffer( begin, end,
429 output_buf + sizeof(output_buf) - ret,
430 ret, buf, size, &olen ) ) != 0 )
431 {
432 return( ret );
433 }
434
435 return( 0 );
436}
437#endif /* MBEDTLS_PEM_WRITE_C */
438
439#endif /* MBEDTLS_PK_WRITE_C */
Note: See TracBrowser for help on using the repository browser.