mbedtls ported to mbed-classic

Fork of mbedtls by Christopher Haster

Committer:
Christopher Haster
Date:
Fri Jan 22 16:44:49 2016 -0600
Revision:
1:24750b9ad5ef
Initial move of mbedtls to mercurial

Who changed what in which revision?

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