pkwrite.c 19 KB

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