Preliminary main mbed library for nexpaq development

Committer:
nexpaq
Date:
Fri Nov 04 20:27:58 2016 +0000
Revision:
0:6c56fb4bc5f0
Moving to library for sharing updates

Who changed what in which revision?

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