initial commit; it works
[psslcertgen.git] / src / libpolarssl / asn1write.c
blob059a5f50d804aaa151610667b5854291476b6adb
1 /*
2 * ASN.1 buffer writing functionality
4 * Copyright (C) 2006-2012, Brainspark B.V.
6 * This file is part of PolarSSL (http://www.polarssl.org)
7 * Lead Maintainer: Paul Bakker <polarssl_maintainer at polarssl.org>
9 * All rights reserved.
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.
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.
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.
26 #include "config.h"
28 #if defined(POLARSSL_ASN1_WRITE_C)
30 #include "asn1write.h"
32 int asn1_write_len( unsigned char **p, unsigned char *start, size_t len )
34 if( len < 0x80 )
36 if( *p - start < 1 )
37 return( POLARSSL_ERR_ASN1_BUF_TOO_SMALL );
39 *--(*p) = len;
40 return( 1 );
43 if( len <= 0xFF )
45 if( *p - start < 2 )
46 return( POLARSSL_ERR_ASN1_BUF_TOO_SMALL );
48 *--(*p) = len;
49 *--(*p) = 0x81;
50 return( 2 );
53 if( *p - start < 3 )
54 return( POLARSSL_ERR_ASN1_BUF_TOO_SMALL );
56 // We assume we never have lengths larger than 65535 bytes
58 *--(*p) = len % 256;
59 *--(*p) = ( len / 256 ) % 256;
60 *--(*p) = 0x82;
62 return( 3 );
65 int asn1_write_tag( unsigned char **p, unsigned char *start, unsigned char tag )
67 if( *p - start < 1 )
68 return( POLARSSL_ERR_ASN1_BUF_TOO_SMALL );
70 *--(*p) = tag;
72 return( 1 );
75 int asn1_write_mpi( unsigned char **p, unsigned char *start, mpi *X )
77 int ret;
78 size_t len = 0;
80 // Write the MPI
82 len = mpi_size( X );
84 if( *p - start < (int) len )
85 return( POLARSSL_ERR_ASN1_BUF_TOO_SMALL );
87 (*p) -= len;
88 mpi_write_binary( X, *p, len );
90 // DER format assumes 2s complement for numbers, so the leftmost bit
91 // should be 0 for positive numbers and 1 for negative numbers.
93 if ( X->s ==1 && **p & 0x80 )
95 if( *p - start < 1 )
96 return( POLARSSL_ERR_ASN1_BUF_TOO_SMALL );
98 *--(*p) = 0x00;
99 len += 1;
102 ASN1_CHK_ADD( len, asn1_write_len( p, start, len ) );
103 ASN1_CHK_ADD( len, asn1_write_tag( p, start, ASN1_INTEGER ) );
105 return( len );
108 int asn1_write_null( unsigned char **p, unsigned char *start )
110 int ret;
111 size_t len = 0;
113 // Write NULL
115 ASN1_CHK_ADD( len, asn1_write_len( p, start, 0) );
116 ASN1_CHK_ADD( len, asn1_write_tag( p, start, ASN1_NULL ) );
118 return( len );
121 int asn1_write_oid( unsigned char **p, unsigned char *start, char *oid )
123 int ret;
124 size_t len = 0;
126 // Write OID
128 len = strlen( oid );
130 if( *p - start < (int) len )
131 return( POLARSSL_ERR_ASN1_BUF_TOO_SMALL );
133 (*p) -= len;
134 memcpy( *p, oid, len );
136 ASN1_CHK_ADD( len , asn1_write_len( p, start, len ) );
137 ASN1_CHK_ADD( len , asn1_write_tag( p, start, ASN1_OID ) );
139 return( len );
142 int asn1_write_algorithm_identifier( unsigned char **p, unsigned char *start,
143 char *algorithm_oid )
145 int ret;
146 size_t null_len = 0;
147 size_t oid_len = 0;
148 size_t len = 0;
150 // Write NULL
152 ASN1_CHK_ADD( null_len, asn1_write_null( p, start ) );
154 // Write OID
156 ASN1_CHK_ADD( oid_len, asn1_write_oid( p, start, algorithm_oid ) );
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,
161 ASN1_CONSTRUCTED | ASN1_SEQUENCE ) );
163 return( len );
166 int asn1_write_int( unsigned char **p, unsigned char *start, int val )
168 int ret;
169 size_t len = 0;
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.
175 if( *p - start < 1 )
176 return( POLARSSL_ERR_ASN1_BUF_TOO_SMALL );
178 len += 1;
179 *--(*p) = val;
181 if ( val > 0 && **p & 0x80 )
183 if( *p - start < 1 )
184 return( POLARSSL_ERR_ASN1_BUF_TOO_SMALL );
186 *--(*p) = 0x00;
187 len += 1;
190 ASN1_CHK_ADD( len, asn1_write_len( p, start, len ) );
191 ASN1_CHK_ADD( len, asn1_write_tag( p, start, ASN1_INTEGER ) );
193 return( len );
196 int asn1_write_printable_string( unsigned char **p, unsigned char *start,
197 char *text )
199 int ret;
200 size_t len = 0;
202 // Write string
204 len = strlen( text );
206 if( *p - start < (int) len )
207 return( POLARSSL_ERR_ASN1_BUF_TOO_SMALL );
209 (*p) -= len;
210 memcpy( *p, text, len );
212 ASN1_CHK_ADD( len, asn1_write_len( p, start, len ) );
213 ASN1_CHK_ADD( len, asn1_write_tag( p, start, ASN1_PRINTABLE_STRING ) );
215 return( len );
218 int asn1_write_ia5_string( unsigned char **p, unsigned char *start,
219 char *text )
221 int ret;
222 size_t len = 0;
224 // Write string
226 len = strlen( text );
228 if( *p - start < (int) len )
229 return( POLARSSL_ERR_ASN1_BUF_TOO_SMALL );
231 (*p) -= len;
232 memcpy( *p, text, len );
234 ASN1_CHK_ADD( len, asn1_write_len( p, start, len ) );
235 ASN1_CHK_ADD( len, asn1_write_tag( p, start, ASN1_IA5_STRING ) );
237 return( len );
241 #endif