pkwrite.c 20 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624
  1. /*
  2. * Public Key layer for writing key files and structures
  3. *
  4. * Copyright The Mbed TLS Contributors
  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. #include "common.h"
  20. #if defined(MBEDTLS_PK_WRITE_C)
  21. #include "mbedtls/pk.h"
  22. #include "mbedtls/asn1write.h"
  23. #include "mbedtls/oid.h"
  24. #include "mbedtls/platform_util.h"
  25. #include "mbedtls/error.h"
  26. #include <string.h>
  27. #if defined(MBEDTLS_RSA_C)
  28. #include "mbedtls/rsa.h"
  29. #endif
  30. #if defined(MBEDTLS_ECP_C)
  31. #include "mbedtls/bignum.h"
  32. #include "mbedtls/ecp.h"
  33. #include "mbedtls/platform_util.h"
  34. #endif
  35. #if defined(MBEDTLS_ECDSA_C)
  36. #include "mbedtls/ecdsa.h"
  37. #endif
  38. #if defined(MBEDTLS_PEM_WRITE_C)
  39. #include "mbedtls/pem.h"
  40. #endif
  41. #if defined(MBEDTLS_USE_PSA_CRYPTO)
  42. #include "psa/crypto.h"
  43. #include "mbedtls/psa_util.h"
  44. #endif
  45. #if defined(MBEDTLS_PLATFORM_C)
  46. #include "mbedtls/platform.h"
  47. #else
  48. #include <stdlib.h>
  49. #define mbedtls_calloc calloc
  50. #define mbedtls_free free
  51. #endif
  52. /* Parameter validation macros based on platform_util.h */
  53. #define PK_VALIDATE_RET( cond ) \
  54. MBEDTLS_INTERNAL_VALIDATE_RET( cond, MBEDTLS_ERR_PK_BAD_INPUT_DATA )
  55. #define PK_VALIDATE( cond ) \
  56. MBEDTLS_INTERNAL_VALIDATE( cond )
  57. #if defined(MBEDTLS_RSA_C)
  58. /*
  59. * RSAPublicKey ::= SEQUENCE {
  60. * modulus INTEGER, -- n
  61. * publicExponent INTEGER -- e
  62. * }
  63. */
  64. static int pk_write_rsa_pubkey( unsigned char **p, unsigned char *start,
  65. mbedtls_rsa_context *rsa )
  66. {
  67. int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
  68. size_t len = 0;
  69. mbedtls_mpi T;
  70. mbedtls_mpi_init( &T );
  71. /* Export E */
  72. if ( ( ret = mbedtls_rsa_export( rsa, NULL, NULL, NULL, NULL, &T ) ) != 0 ||
  73. ( ret = mbedtls_asn1_write_mpi( p, start, &T ) ) < 0 )
  74. goto end_of_export;
  75. len += ret;
  76. /* Export N */
  77. if ( ( ret = mbedtls_rsa_export( rsa, &T, NULL, NULL, NULL, NULL ) ) != 0 ||
  78. ( ret = mbedtls_asn1_write_mpi( p, start, &T ) ) < 0 )
  79. goto end_of_export;
  80. len += ret;
  81. end_of_export:
  82. mbedtls_mpi_free( &T );
  83. if( ret < 0 )
  84. return( ret );
  85. MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_len( p, start, len ) );
  86. MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_tag( p, start, MBEDTLS_ASN1_CONSTRUCTED |
  87. MBEDTLS_ASN1_SEQUENCE ) );
  88. return( (int) len );
  89. }
  90. #endif /* MBEDTLS_RSA_C */
  91. #if defined(MBEDTLS_ECP_C)
  92. /*
  93. * EC public key is an EC point
  94. */
  95. static int pk_write_ec_pubkey( unsigned char **p, unsigned char *start,
  96. mbedtls_ecp_keypair *ec )
  97. {
  98. int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
  99. size_t len = 0;
  100. unsigned char buf[MBEDTLS_ECP_MAX_PT_LEN];
  101. if( ( ret = mbedtls_ecp_point_write_binary( &ec->grp, &ec->Q,
  102. MBEDTLS_ECP_PF_UNCOMPRESSED,
  103. &len, buf, sizeof( buf ) ) ) != 0 )
  104. {
  105. return( ret );
  106. }
  107. if( *p < start || (size_t)( *p - start ) < len )
  108. return( MBEDTLS_ERR_ASN1_BUF_TOO_SMALL );
  109. *p -= len;
  110. memcpy( *p, buf, len );
  111. return( (int) len );
  112. }
  113. /*
  114. * ECParameters ::= CHOICE {
  115. * namedCurve OBJECT IDENTIFIER
  116. * }
  117. */
  118. static int pk_write_ec_param( unsigned char **p, unsigned char *start,
  119. mbedtls_ecp_keypair *ec )
  120. {
  121. int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
  122. size_t len = 0;
  123. const char *oid;
  124. size_t oid_len;
  125. if( ( ret = mbedtls_oid_get_oid_by_ec_grp( ec->grp.id, &oid, &oid_len ) ) != 0 )
  126. return( ret );
  127. MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_oid( p, start, oid, oid_len ) );
  128. return( (int) len );
  129. }
  130. /*
  131. * privateKey OCTET STRING -- always of length ceil(log2(n)/8)
  132. */
  133. static int pk_write_ec_private( unsigned char **p, unsigned char *start,
  134. mbedtls_ecp_keypair *ec )
  135. {
  136. int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
  137. size_t byte_length = ( ec->grp.pbits + 7 ) / 8;
  138. unsigned char tmp[MBEDTLS_ECP_MAX_BYTES];
  139. ret = mbedtls_ecp_write_key( ec, tmp, byte_length );
  140. if( ret != 0 )
  141. goto exit;
  142. ret = mbedtls_asn1_write_octet_string( p, start, tmp, byte_length );
  143. exit:
  144. mbedtls_platform_zeroize( tmp, byte_length );
  145. return( ret );
  146. }
  147. #endif /* MBEDTLS_ECP_C */
  148. int mbedtls_pk_write_pubkey( unsigned char **p, unsigned char *start,
  149. const mbedtls_pk_context *key )
  150. {
  151. int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
  152. size_t len = 0;
  153. PK_VALIDATE_RET( p != NULL );
  154. PK_VALIDATE_RET( *p != NULL );
  155. PK_VALIDATE_RET( start != NULL );
  156. PK_VALIDATE_RET( key != NULL );
  157. #if defined(MBEDTLS_RSA_C)
  158. if( mbedtls_pk_get_type( key ) == MBEDTLS_PK_RSA )
  159. MBEDTLS_ASN1_CHK_ADD( len, pk_write_rsa_pubkey( p, start, mbedtls_pk_rsa( *key ) ) );
  160. else
  161. #endif
  162. #if defined(MBEDTLS_ECP_C)
  163. if( mbedtls_pk_get_type( key ) == MBEDTLS_PK_ECKEY )
  164. MBEDTLS_ASN1_CHK_ADD( len, pk_write_ec_pubkey( p, start, mbedtls_pk_ec( *key ) ) );
  165. else
  166. #endif
  167. #if defined(MBEDTLS_USE_PSA_CRYPTO)
  168. if( mbedtls_pk_get_type( key ) == MBEDTLS_PK_OPAQUE )
  169. {
  170. size_t buffer_size;
  171. psa_key_id_t* key_id = (psa_key_id_t*) key->pk_ctx;
  172. if ( *p < start )
  173. return( MBEDTLS_ERR_PK_BAD_INPUT_DATA );
  174. buffer_size = (size_t)( *p - start );
  175. if ( psa_export_public_key( *key_id, start, buffer_size, &len )
  176. != PSA_SUCCESS )
  177. {
  178. return( MBEDTLS_ERR_PK_BAD_INPUT_DATA );
  179. }
  180. else
  181. {
  182. *p -= len;
  183. memmove( *p, start, len );
  184. }
  185. }
  186. else
  187. #endif /* MBEDTLS_USE_PSA_CRYPTO */
  188. return( MBEDTLS_ERR_PK_FEATURE_UNAVAILABLE );
  189. return( (int) len );
  190. }
  191. int mbedtls_pk_write_pubkey_der( mbedtls_pk_context *key, unsigned char *buf, size_t size )
  192. {
  193. int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
  194. unsigned char *c;
  195. size_t len = 0, par_len = 0, oid_len;
  196. mbedtls_pk_type_t pk_type;
  197. const char *oid;
  198. PK_VALIDATE_RET( key != NULL );
  199. if( size == 0 )
  200. return( MBEDTLS_ERR_ASN1_BUF_TOO_SMALL );
  201. PK_VALIDATE_RET( buf != NULL );
  202. c = buf + size;
  203. MBEDTLS_ASN1_CHK_ADD( len, mbedtls_pk_write_pubkey( &c, buf, key ) );
  204. if( c - buf < 1 )
  205. return( MBEDTLS_ERR_ASN1_BUF_TOO_SMALL );
  206. /*
  207. * SubjectPublicKeyInfo ::= SEQUENCE {
  208. * algorithm AlgorithmIdentifier,
  209. * subjectPublicKey BIT STRING }
  210. */
  211. *--c = 0;
  212. len += 1;
  213. MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_len( &c, buf, len ) );
  214. MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_tag( &c, buf, MBEDTLS_ASN1_BIT_STRING ) );
  215. pk_type = mbedtls_pk_get_type( key );
  216. #if defined(MBEDTLS_ECP_C)
  217. if( pk_type == MBEDTLS_PK_ECKEY )
  218. {
  219. MBEDTLS_ASN1_CHK_ADD( par_len, pk_write_ec_param( &c, buf, mbedtls_pk_ec( *key ) ) );
  220. }
  221. #endif
  222. #if defined(MBEDTLS_USE_PSA_CRYPTO)
  223. if( pk_type == MBEDTLS_PK_OPAQUE )
  224. {
  225. psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
  226. psa_key_type_t key_type;
  227. psa_key_id_t key_id;
  228. psa_ecc_family_t curve;
  229. size_t bits;
  230. key_id = *((psa_key_id_t*) key->pk_ctx );
  231. if( PSA_SUCCESS != psa_get_key_attributes( key_id, &attributes ) )
  232. return( MBEDTLS_ERR_PK_HW_ACCEL_FAILED );
  233. key_type = psa_get_key_type( &attributes );
  234. bits = psa_get_key_bits( &attributes );
  235. psa_reset_key_attributes( &attributes );
  236. curve = PSA_KEY_TYPE_ECC_GET_FAMILY( key_type );
  237. if( curve == 0 )
  238. return( MBEDTLS_ERR_PK_FEATURE_UNAVAILABLE );
  239. ret = mbedtls_psa_get_ecc_oid_from_id( curve, bits, &oid, &oid_len );
  240. if( ret != 0 )
  241. return( MBEDTLS_ERR_PK_FEATURE_UNAVAILABLE );
  242. /* Write EC algorithm parameters; that's akin
  243. * to pk_write_ec_param() above. */
  244. MBEDTLS_ASN1_CHK_ADD( par_len, mbedtls_asn1_write_oid( &c, buf,
  245. oid, oid_len ) );
  246. /* The rest of the function works as for legacy EC contexts. */
  247. pk_type = MBEDTLS_PK_ECKEY;
  248. }
  249. #endif /* MBEDTLS_USE_PSA_CRYPTO */
  250. if( ( ret = mbedtls_oid_get_oid_by_pk_alg( pk_type, &oid,
  251. &oid_len ) ) != 0 )
  252. {
  253. return( ret );
  254. }
  255. MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_algorithm_identifier( &c, buf, oid, oid_len,
  256. par_len ) );
  257. MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_len( &c, buf, len ) );
  258. MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_tag( &c, buf, MBEDTLS_ASN1_CONSTRUCTED |
  259. MBEDTLS_ASN1_SEQUENCE ) );
  260. return( (int) len );
  261. }
  262. int mbedtls_pk_write_key_der( mbedtls_pk_context *key, unsigned char *buf, size_t size )
  263. {
  264. int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
  265. unsigned char *c;
  266. size_t len = 0;
  267. PK_VALIDATE_RET( key != NULL );
  268. if( size == 0 )
  269. return( MBEDTLS_ERR_ASN1_BUF_TOO_SMALL );
  270. PK_VALIDATE_RET( buf != NULL );
  271. c = buf + size;
  272. #if defined(MBEDTLS_RSA_C)
  273. if( mbedtls_pk_get_type( key ) == MBEDTLS_PK_RSA )
  274. {
  275. mbedtls_mpi T; /* Temporary holding the exported parameters */
  276. mbedtls_rsa_context *rsa = mbedtls_pk_rsa( *key );
  277. /*
  278. * Export the parameters one after another to avoid simultaneous copies.
  279. */
  280. mbedtls_mpi_init( &T );
  281. /* Export QP */
  282. if( ( ret = mbedtls_rsa_export_crt( rsa, NULL, NULL, &T ) ) != 0 ||
  283. ( ret = mbedtls_asn1_write_mpi( &c, buf, &T ) ) < 0 )
  284. goto end_of_export;
  285. len += ret;
  286. /* Export DQ */
  287. if( ( ret = mbedtls_rsa_export_crt( rsa, NULL, &T, NULL ) ) != 0 ||
  288. ( ret = mbedtls_asn1_write_mpi( &c, buf, &T ) ) < 0 )
  289. goto end_of_export;
  290. len += ret;
  291. /* Export DP */
  292. if( ( ret = mbedtls_rsa_export_crt( rsa, &T, NULL, NULL ) ) != 0 ||
  293. ( ret = mbedtls_asn1_write_mpi( &c, buf, &T ) ) < 0 )
  294. goto end_of_export;
  295. len += ret;
  296. /* Export Q */
  297. if ( ( ret = mbedtls_rsa_export( rsa, NULL, NULL,
  298. &T, NULL, NULL ) ) != 0 ||
  299. ( ret = mbedtls_asn1_write_mpi( &c, buf, &T ) ) < 0 )
  300. goto end_of_export;
  301. len += ret;
  302. /* Export P */
  303. if ( ( ret = mbedtls_rsa_export( rsa, NULL, &T,
  304. NULL, NULL, NULL ) ) != 0 ||
  305. ( ret = mbedtls_asn1_write_mpi( &c, buf, &T ) ) < 0 )
  306. goto end_of_export;
  307. len += ret;
  308. /* Export D */
  309. if ( ( ret = mbedtls_rsa_export( rsa, NULL, NULL,
  310. NULL, &T, NULL ) ) != 0 ||
  311. ( ret = mbedtls_asn1_write_mpi( &c, buf, &T ) ) < 0 )
  312. goto end_of_export;
  313. len += ret;
  314. /* Export E */
  315. if ( ( ret = mbedtls_rsa_export( rsa, NULL, NULL,
  316. NULL, NULL, &T ) ) != 0 ||
  317. ( ret = mbedtls_asn1_write_mpi( &c, buf, &T ) ) < 0 )
  318. goto end_of_export;
  319. len += ret;
  320. /* Export N */
  321. if ( ( ret = mbedtls_rsa_export( rsa, &T, NULL,
  322. NULL, NULL, NULL ) ) != 0 ||
  323. ( ret = mbedtls_asn1_write_mpi( &c, buf, &T ) ) < 0 )
  324. goto end_of_export;
  325. len += ret;
  326. end_of_export:
  327. mbedtls_mpi_free( &T );
  328. if( ret < 0 )
  329. return( ret );
  330. MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_int( &c, buf, 0 ) );
  331. MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_len( &c, buf, len ) );
  332. MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_tag( &c,
  333. buf, MBEDTLS_ASN1_CONSTRUCTED |
  334. MBEDTLS_ASN1_SEQUENCE ) );
  335. }
  336. else
  337. #endif /* MBEDTLS_RSA_C */
  338. #if defined(MBEDTLS_ECP_C)
  339. if( mbedtls_pk_get_type( key ) == MBEDTLS_PK_ECKEY )
  340. {
  341. mbedtls_ecp_keypair *ec = mbedtls_pk_ec( *key );
  342. size_t pub_len = 0, par_len = 0;
  343. /*
  344. * RFC 5915, or SEC1 Appendix C.4
  345. *
  346. * ECPrivateKey ::= SEQUENCE {
  347. * version INTEGER { ecPrivkeyVer1(1) } (ecPrivkeyVer1),
  348. * privateKey OCTET STRING,
  349. * parameters [0] ECParameters {{ NamedCurve }} OPTIONAL,
  350. * publicKey [1] BIT STRING OPTIONAL
  351. * }
  352. */
  353. /* publicKey */
  354. MBEDTLS_ASN1_CHK_ADD( pub_len, pk_write_ec_pubkey( &c, buf, ec ) );
  355. if( c - buf < 1 )
  356. return( MBEDTLS_ERR_ASN1_BUF_TOO_SMALL );
  357. *--c = 0;
  358. pub_len += 1;
  359. MBEDTLS_ASN1_CHK_ADD( pub_len, mbedtls_asn1_write_len( &c, buf, pub_len ) );
  360. MBEDTLS_ASN1_CHK_ADD( pub_len, mbedtls_asn1_write_tag( &c, buf, MBEDTLS_ASN1_BIT_STRING ) );
  361. MBEDTLS_ASN1_CHK_ADD( pub_len, mbedtls_asn1_write_len( &c, buf, pub_len ) );
  362. MBEDTLS_ASN1_CHK_ADD( pub_len, mbedtls_asn1_write_tag( &c, buf,
  363. MBEDTLS_ASN1_CONTEXT_SPECIFIC | MBEDTLS_ASN1_CONSTRUCTED | 1 ) );
  364. len += pub_len;
  365. /* parameters */
  366. MBEDTLS_ASN1_CHK_ADD( par_len, pk_write_ec_param( &c, buf, ec ) );
  367. MBEDTLS_ASN1_CHK_ADD( par_len, mbedtls_asn1_write_len( &c, buf, par_len ) );
  368. MBEDTLS_ASN1_CHK_ADD( par_len, mbedtls_asn1_write_tag( &c, buf,
  369. MBEDTLS_ASN1_CONTEXT_SPECIFIC | MBEDTLS_ASN1_CONSTRUCTED | 0 ) );
  370. len += par_len;
  371. /* privateKey */
  372. MBEDTLS_ASN1_CHK_ADD( len, pk_write_ec_private( &c, buf, ec ) );
  373. /* version */
  374. MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_int( &c, buf, 1 ) );
  375. MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_len( &c, buf, len ) );
  376. MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_tag( &c, buf, MBEDTLS_ASN1_CONSTRUCTED |
  377. MBEDTLS_ASN1_SEQUENCE ) );
  378. }
  379. else
  380. #endif /* MBEDTLS_ECP_C */
  381. return( MBEDTLS_ERR_PK_FEATURE_UNAVAILABLE );
  382. return( (int) len );
  383. }
  384. #if defined(MBEDTLS_PEM_WRITE_C)
  385. #define PEM_BEGIN_PUBLIC_KEY "-----BEGIN PUBLIC KEY-----\n"
  386. #define PEM_END_PUBLIC_KEY "-----END PUBLIC KEY-----\n"
  387. #define PEM_BEGIN_PRIVATE_KEY_RSA "-----BEGIN RSA PRIVATE KEY-----\n"
  388. #define PEM_END_PRIVATE_KEY_RSA "-----END RSA PRIVATE KEY-----\n"
  389. #define PEM_BEGIN_PRIVATE_KEY_EC "-----BEGIN EC PRIVATE KEY-----\n"
  390. #define PEM_END_PRIVATE_KEY_EC "-----END EC PRIVATE KEY-----\n"
  391. /*
  392. * Max sizes of key per types. Shown as tag + len (+ content).
  393. */
  394. #if defined(MBEDTLS_RSA_C)
  395. /*
  396. * RSA public keys:
  397. * SubjectPublicKeyInfo ::= SEQUENCE { 1 + 3
  398. * algorithm AlgorithmIdentifier, 1 + 1 (sequence)
  399. * + 1 + 1 + 9 (rsa oid)
  400. * + 1 + 1 (params null)
  401. * subjectPublicKey BIT STRING } 1 + 3 + (1 + below)
  402. * RSAPublicKey ::= SEQUENCE { 1 + 3
  403. * modulus INTEGER, -- n 1 + 3 + MPI_MAX + 1
  404. * publicExponent INTEGER -- e 1 + 3 + MPI_MAX + 1
  405. * }
  406. */
  407. #define RSA_PUB_DER_MAX_BYTES ( 38 + 2 * MBEDTLS_MPI_MAX_SIZE )
  408. /*
  409. * RSA private keys:
  410. * RSAPrivateKey ::= SEQUENCE { 1 + 3
  411. * version Version, 1 + 1 + 1
  412. * modulus INTEGER, 1 + 3 + MPI_MAX + 1
  413. * publicExponent INTEGER, 1 + 3 + MPI_MAX + 1
  414. * privateExponent INTEGER, 1 + 3 + MPI_MAX + 1
  415. * prime1 INTEGER, 1 + 3 + MPI_MAX / 2 + 1
  416. * prime2 INTEGER, 1 + 3 + MPI_MAX / 2 + 1
  417. * exponent1 INTEGER, 1 + 3 + MPI_MAX / 2 + 1
  418. * exponent2 INTEGER, 1 + 3 + MPI_MAX / 2 + 1
  419. * coefficient INTEGER, 1 + 3 + MPI_MAX / 2 + 1
  420. * otherPrimeInfos OtherPrimeInfos OPTIONAL 0 (not supported)
  421. * }
  422. */
  423. #define MPI_MAX_SIZE_2 ( MBEDTLS_MPI_MAX_SIZE / 2 + \
  424. MBEDTLS_MPI_MAX_SIZE % 2 )
  425. #define RSA_PRV_DER_MAX_BYTES ( 47 + 3 * MBEDTLS_MPI_MAX_SIZE \
  426. + 5 * MPI_MAX_SIZE_2 )
  427. #else /* MBEDTLS_RSA_C */
  428. #define RSA_PUB_DER_MAX_BYTES 0
  429. #define RSA_PRV_DER_MAX_BYTES 0
  430. #endif /* MBEDTLS_RSA_C */
  431. #if defined(MBEDTLS_ECP_C)
  432. /*
  433. * EC public keys:
  434. * SubjectPublicKeyInfo ::= SEQUENCE { 1 + 2
  435. * algorithm AlgorithmIdentifier, 1 + 1 (sequence)
  436. * + 1 + 1 + 7 (ec oid)
  437. * + 1 + 1 + 9 (namedCurve oid)
  438. * subjectPublicKey BIT STRING 1 + 2 + 1 [1]
  439. * + 1 (point format) [1]
  440. * + 2 * ECP_MAX (coords) [1]
  441. * }
  442. */
  443. #define ECP_PUB_DER_MAX_BYTES ( 30 + 2 * MBEDTLS_ECP_MAX_BYTES )
  444. /*
  445. * EC private keys:
  446. * ECPrivateKey ::= SEQUENCE { 1 + 2
  447. * version INTEGER , 1 + 1 + 1
  448. * privateKey OCTET STRING, 1 + 1 + ECP_MAX
  449. * parameters [0] ECParameters OPTIONAL, 1 + 1 + (1 + 1 + 9)
  450. * publicKey [1] BIT STRING OPTIONAL 1 + 2 + [1] above
  451. * }
  452. */
  453. #define ECP_PRV_DER_MAX_BYTES ( 29 + 3 * MBEDTLS_ECP_MAX_BYTES )
  454. #else /* MBEDTLS_ECP_C */
  455. #define ECP_PUB_DER_MAX_BYTES 0
  456. #define ECP_PRV_DER_MAX_BYTES 0
  457. #endif /* MBEDTLS_ECP_C */
  458. #define PUB_DER_MAX_BYTES ( RSA_PUB_DER_MAX_BYTES > ECP_PUB_DER_MAX_BYTES ? \
  459. RSA_PUB_DER_MAX_BYTES : ECP_PUB_DER_MAX_BYTES )
  460. #define PRV_DER_MAX_BYTES ( RSA_PRV_DER_MAX_BYTES > ECP_PRV_DER_MAX_BYTES ? \
  461. RSA_PRV_DER_MAX_BYTES : ECP_PRV_DER_MAX_BYTES )
  462. int mbedtls_pk_write_pubkey_pem( mbedtls_pk_context *key, unsigned char *buf, size_t size )
  463. {
  464. int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
  465. unsigned char output_buf[PUB_DER_MAX_BYTES];
  466. size_t olen = 0;
  467. PK_VALIDATE_RET( key != NULL );
  468. PK_VALIDATE_RET( buf != NULL || size == 0 );
  469. if( ( ret = mbedtls_pk_write_pubkey_der( key, output_buf,
  470. sizeof(output_buf) ) ) < 0 )
  471. {
  472. return( ret );
  473. }
  474. if( ( ret = mbedtls_pem_write_buffer( PEM_BEGIN_PUBLIC_KEY, PEM_END_PUBLIC_KEY,
  475. output_buf + sizeof(output_buf) - ret,
  476. ret, buf, size, &olen ) ) != 0 )
  477. {
  478. return( ret );
  479. }
  480. return( 0 );
  481. }
  482. int mbedtls_pk_write_key_pem( mbedtls_pk_context *key, unsigned char *buf, size_t size )
  483. {
  484. int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
  485. unsigned char output_buf[PRV_DER_MAX_BYTES];
  486. const char *begin, *end;
  487. size_t olen = 0;
  488. PK_VALIDATE_RET( key != NULL );
  489. PK_VALIDATE_RET( buf != NULL || size == 0 );
  490. if( ( ret = mbedtls_pk_write_key_der( key, output_buf, sizeof(output_buf) ) ) < 0 )
  491. return( ret );
  492. #if defined(MBEDTLS_RSA_C)
  493. if( mbedtls_pk_get_type( key ) == MBEDTLS_PK_RSA )
  494. {
  495. begin = PEM_BEGIN_PRIVATE_KEY_RSA;
  496. end = PEM_END_PRIVATE_KEY_RSA;
  497. }
  498. else
  499. #endif
  500. #if defined(MBEDTLS_ECP_C)
  501. if( mbedtls_pk_get_type( key ) == MBEDTLS_PK_ECKEY )
  502. {
  503. begin = PEM_BEGIN_PRIVATE_KEY_EC;
  504. end = PEM_END_PRIVATE_KEY_EC;
  505. }
  506. else
  507. #endif
  508. return( MBEDTLS_ERR_PK_FEATURE_UNAVAILABLE );
  509. if( ( ret = mbedtls_pem_write_buffer( begin, end,
  510. output_buf + sizeof(output_buf) - ret,
  511. ret, buf, size, &olen ) ) != 0 )
  512. {
  513. return( ret );
  514. }
  515. return( 0 );
  516. }
  517. #endif /* MBEDTLS_PEM_WRITE_C */
  518. #endif /* MBEDTLS_PK_WRITE_C */