PolarSSL v1.2.5
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_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  return( len );
106 }
107 
108 int asn1_write_null( unsigned char **p, unsigned char *start )
109 {
110  int ret;
111  size_t len = 0;
112 
113  // Write NULL
114  //
115  ASN1_CHK_ADD( len, asn1_write_len( p, start, 0) );
116  ASN1_CHK_ADD( len, asn1_write_tag( p, start, ASN1_NULL ) );
117 
118  return( len );
119 }
120 
121 int asn1_write_oid( unsigned char **p, unsigned char *start, char *oid )
122 {
123  int ret;
124  size_t len = 0;
125 
126  // Write OID
127  //
128  len = strlen( oid );
129 
130  if( *p - start < (int) len )
132 
133  (*p) -= len;
134  memcpy( *p, oid, len );
135 
136  ASN1_CHK_ADD( len , asn1_write_len( p, start, len ) );
137  ASN1_CHK_ADD( len , asn1_write_tag( p, start, ASN1_OID ) );
138 
139  return( len );
140 }
141 
142 int asn1_write_algorithm_identifier( unsigned char **p, unsigned char *start,
143  char *algorithm_oid )
144 {
145  int ret;
146  size_t null_len = 0;
147  size_t oid_len = 0;
148  size_t len = 0;
149 
150  // Write NULL
151  //
152  ASN1_CHK_ADD( null_len, asn1_write_null( p, start ) );
153 
154  // Write OID
155  //
156  ASN1_CHK_ADD( oid_len, asn1_write_oid( p, start, algorithm_oid ) );
157 
158  len = oid_len + null_len;
159  ASN1_CHK_ADD( len, asn1_write_len( p, start, oid_len + null_len ) );
160  ASN1_CHK_ADD( len, asn1_write_tag( p, start,
162 
163  return( len );
164 }
165 
166 int asn1_write_int( unsigned char **p, unsigned char *start, int val )
167 {
168  int ret;
169  size_t len = 0;
170 
171  // TODO negative values and values larger than 128
172  // DER format assumes 2s complement for numbers, so the leftmost bit
173  // should be 0 for positive numbers and 1 for negative numbers.
174  //
175  if( *p - start < 1 )
177 
178  len += 1;
179  *--(*p) = val;
180 
181  if ( val > 0 && **p & 0x80 )
182  {
183  if( *p - start < 1 )
185 
186  *--(*p) = 0x00;
187  len += 1;
188  }
189 
190  ASN1_CHK_ADD( len, asn1_write_len( p, start, len ) );
191  ASN1_CHK_ADD( len, asn1_write_tag( p, start, ASN1_INTEGER ) );
192 
193  return( len );
194 }
195 
196 int asn1_write_printable_string( unsigned char **p, unsigned char *start,
197  char *text )
198 {
199  int ret;
200  size_t len = 0;
201 
202  // Write string
203  //
204  len = strlen( text );
205 
206  if( *p - start < (int) len )
208 
209  (*p) -= len;
210  memcpy( *p, text, len );
211 
212  ASN1_CHK_ADD( len, asn1_write_len( p, start, len ) );
214 
215  return( len );
216 }
217 
218 int asn1_write_ia5_string( unsigned char **p, unsigned char *start,
219  char *text )
220 {
221  int ret;
222  size_t len = 0;
223 
224  // Write string
225  //
226  len = strlen( text );
227 
228  if( *p - start < (int) len )
230 
231  (*p) -= len;
232  memcpy( *p, text, len );
233 
234  ASN1_CHK_ADD( len, asn1_write_len( p, start, len ) );
235  ASN1_CHK_ADD( len, asn1_write_tag( p, start, ASN1_IA5_STRING ) );
236 
237  return( len );
238 }
239 
240 
241 #endif