PolarSSL v1.2.12
asn1write.c
Go to the documentation of this file.
1 /*
2  * ASN.1 buffer writing functionality
3  *
4  * Copyright (C) 2006-2012, Brainspark B.V.
5  *
6  * This file is part of PolarSSL (http://www.polarssl.org)
7  * Lead Maintainer: Paul Bakker <polarssl_maintainer at polarssl.org>
8  *
9  * All rights reserved.
10  *
11  * This program is free software; you can redistribute it and/or modify
12  * it under the terms of the GNU General Public License as published by
13  * the Free Software Foundation; either version 2 of the License, or
14  * (at your option) any later version.
15  *
16  * This program is distributed in the hope that it will be useful,
17  * but WITHOUT ANY WARRANTY; without even the implied warranty of
18  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19  * GNU General Public License for more details.
20  *
21  * You should have received a copy of the GNU General Public License along
22  * with this program; if not, write to the Free Software Foundation, Inc.,
23  * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
24  */
25 
26 #include "polarssl/config.h"
27 
28 #if defined(POLARSSL_ASN1_WRITE_C)
29 
30 #include "polarssl/asn1write.h"
31 
32 int asn1_write_len( unsigned char **p, unsigned char *start, size_t len )
33 {
34  if( len < 0x80 )
35  {
36  if( *p - start < 1 )
38 
39  *--(*p) = len;
40  return( 1 );
41  }
42 
43  if( len <= 0xFF )
44  {
45  if( *p - start < 2 )
47 
48  *--(*p) = len;
49  *--(*p) = 0x81;
50  return( 2 );
51  }
52 
53  if( *p - start < 3 )
55 
56  // We assume we never have lengths larger than 65535 bytes
57  //
58  *--(*p) = len % 256;
59  *--(*p) = ( len / 256 ) % 256;
60  *--(*p) = 0x82;
61 
62  return( 3 );
63 }
64 
65 int asn1_write_tag( unsigned char **p, unsigned char *start, unsigned char tag )
66 {
67  if( *p - start < 1 )
69 
70  *--(*p) = tag;
71 
72  return( 1 );
73 }
74 
75 int asn1_write_mpi( unsigned char **p, unsigned char *start, mpi *X )
76 {
77  int ret;
78  size_t len = 0;
79 
80  // Write the MPI
81  //
82  len = mpi_size( X );
83 
84  if( *p - start < (int) len )
86 
87  (*p) -= len;
88  MPI_CHK( mpi_write_binary( X, *p, len ) );
89 
90  // DER format assumes 2s complement for numbers, so the leftmost bit
91  // should be 0 for positive numbers and 1 for negative numbers.
92  //
93  if ( X->s ==1 && **p & 0x80 )
94  {
95  if( *p - start < 1 )
97 
98  *--(*p) = 0x00;
99  len += 1;
100  }
101 
102  ASN1_CHK_ADD( len, asn1_write_len( p, start, len ) );
103  ASN1_CHK_ADD( len, asn1_write_tag( p, start, ASN1_INTEGER ) );
104 
105  ret = (int) len;
106 
107 cleanup:
108  return( ret );
109 }
110 
111 int asn1_write_null( unsigned char **p, unsigned char *start )
112 {
113  int ret;
114  size_t len = 0;
115 
116  // Write NULL
117  //
118  ASN1_CHK_ADD( len, asn1_write_len( p, start, 0) );
119  ASN1_CHK_ADD( len, asn1_write_tag( p, start, ASN1_NULL ) );
120 
121  return( len );
122 }
123 
124 int asn1_write_oid( unsigned char **p, unsigned char *start, char *oid )
125 {
126  int ret;
127  size_t len = 0;
128 
129  // Write OID
130  //
131  len = strlen( oid );
132 
133  if( *p - start < (int) len )
135 
136  (*p) -= len;
137  memcpy( *p, oid, len );
138 
139  ASN1_CHK_ADD( len , asn1_write_len( p, start, len ) );
140  ASN1_CHK_ADD( len , asn1_write_tag( p, start, ASN1_OID ) );
141 
142  return( len );
143 }
144 
145 int asn1_write_algorithm_identifier( unsigned char **p, unsigned char *start,
146  char *algorithm_oid )
147 {
148  int ret;
149  size_t null_len = 0;
150  size_t oid_len = 0;
151  size_t len = 0;
152 
153  // Write NULL
154  //
155  ASN1_CHK_ADD( null_len, asn1_write_null( p, start ) );
156 
157  // Write OID
158  //
159  ASN1_CHK_ADD( oid_len, asn1_write_oid( p, start, algorithm_oid ) );
160 
161  len = oid_len + null_len;
162  ASN1_CHK_ADD( len, asn1_write_len( p, start, oid_len + null_len ) );
163  ASN1_CHK_ADD( len, asn1_write_tag( p, start,
165 
166  return( len );
167 }
168 
169 int asn1_write_int( unsigned char **p, unsigned char *start, int val )
170 {
171  int ret;
172  size_t len = 0;
173 
174  // TODO negative values and values larger than 128
175  // DER format assumes 2s complement for numbers, so the leftmost bit
176  // should be 0 for positive numbers and 1 for negative numbers.
177  //
178  if( *p - start < 1 )
180 
181  len += 1;
182  *--(*p) = val;
183 
184  if ( val > 0 && **p & 0x80 )
185  {
186  if( *p - start < 1 )
188 
189  *--(*p) = 0x00;
190  len += 1;
191  }
192 
193  ASN1_CHK_ADD( len, asn1_write_len( p, start, len ) );
194  ASN1_CHK_ADD( len, asn1_write_tag( p, start, ASN1_INTEGER ) );
195 
196  return( len );
197 }
198 
199 int asn1_write_printable_string( unsigned char **p, unsigned char *start,
200  char *text )
201 {
202  int ret;
203  size_t len = 0;
204 
205  // Write string
206  //
207  len = strlen( text );
208 
209  if( *p - start < (int) len )
211 
212  (*p) -= len;
213  memcpy( *p, text, len );
214 
215  ASN1_CHK_ADD( len, asn1_write_len( p, start, len ) );
217 
218  return( len );
219 }
220 
221 int asn1_write_ia5_string( unsigned char **p, unsigned char *start,
222  char *text )
223 {
224  int ret;
225  size_t len = 0;
226 
227  // Write string
228  //
229  len = strlen( text );
230 
231  if( *p - start < (int) len )
233 
234  (*p) -= len;
235  memcpy( *p, text, len );
236 
237  ASN1_CHK_ADD( len, asn1_write_len( p, start, len ) );
238  ASN1_CHK_ADD( len, asn1_write_tag( p, start, ASN1_IA5_STRING ) );
239 
240  return( len );
241 }
242 
243 
244 #endif
#define ASN1_NULL
Definition: asn1.h:75
#define ASN1_PRINTABLE_STRING
Definition: asn1.h:80
#define ASN1_OID
Definition: asn1.h:76
int s
Definition: bignum.h:166
#define POLARSSL_ERR_ASN1_BUF_TOO_SMALL
Buffer too small when writing ASN.1 data structure.
Definition: asn1.h:56
#define ASN1_SEQUENCE
Definition: asn1.h:78
Configuration options (set of defines)
#define ASN1_CONSTRUCTED
Definition: asn1.h:88
MPI structure.
Definition: bignum.h:164
int asn1_write_len(unsigned char **p, unsigned char *start, size_t len)
int asn1_write_algorithm_identifier(unsigned char **p, unsigned char *start, char *algorithm_oid)
#define ASN1_INTEGER
Definition: asn1.h:72
int asn1_write_null(unsigned char **p, unsigned char *start)
int asn1_write_mpi(unsigned char **p, unsigned char *start, mpi *X)
int asn1_write_int(unsigned char **p, unsigned char *start, int val)
#define ASN1_CHK_ADD(g, f)
Definition: asn1write.h:32
#define ASN1_IA5_STRING
Definition: asn1.h:82
int asn1_write_printable_string(unsigned char **p, unsigned char *start, char *text)
size_t mpi_size(const mpi *X)
Return the total size in bytes.
int asn1_write_oid(unsigned char **p, unsigned char *start, char *oid)
int mpi_write_binary(const mpi *X, unsigned char *buf, size_t buflen)
Export X into unsigned binary data, big endian.
ASN.1 buffer writing functionality.
int asn1_write_ia5_string(unsigned char **p, unsigned char *start, char *text)
int asn1_write_tag(unsigned char **p, unsigned char *start, unsigned char tag)
#define MPI_CHK(f)
Definition: bignum.h:61