5788777f2fec513cbe236cb7ec5408b2dc7486e4
[exim.git] / src / src / pdkim / part-x509parse.c
1 #include "crypt_ver.h"
2
3 #ifdef SHA_POLARSSL     /* remainder of file */
4
5 #include "polarssl/bignum.h"
6 #include "polarssl/part-x509.h"
7 #include "polarssl/private-x509parse_c.h"
8
9 /* all calls are from src/pdkim/pdkim-rsa.c */
10
11 /* *************** begin copy from x509parse.c ********************/
12 /*
13  *  X.509 certificate and private key decoding
14  *
15  *  Copyright (C) 2006-2010, Brainspark B.V.
16  *
17  *  This file is part of PolarSSL (http://www.polarssl.org)
18  *  Lead Maintainer: Paul Bakker <polarssl_maintainer at polarssl.org>
19  *
20  *  All rights reserved.
21  *
22  *  This program is free software; you can redistribute it and/or modify
23  *  it under the terms of the GNU General Public License as published by
24  *  the Free Software Foundation; either version 2 of the License, or
25  *  (at your option) any later version.
26  *
27  *  This program is distributed in the hope that it will be useful,
28  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
29  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
30  *  GNU General Public License for more details.
31  *
32  *  You should have received a copy of the GNU General Public License along
33  *  with this program; if not, write to the Free Software Foundation, Inc.,
34  *  51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
35  */
36 /*
37  *  The ITU-T X.509 standard defines a certificat format for PKI.
38  *
39  *  http://www.ietf.org/rfc/rfc2459.txt
40  *  http://www.ietf.org/rfc/rfc3279.txt
41  *
42  *  ftp://ftp.rsasecurity.com/pub/pkcs/ascii/pkcs-1v2.asc
43  *
44  *  http://www.itu.int/ITU-T/studygroups/com17/languages/X.680-0207.pdf
45  *  http://www.itu.int/ITU-T/studygroups/com17/languages/X.690-0207.pdf
46  */
47
48
49 /*
50  * ASN.1 DER decoding routines
51  */
52 static int asn1_get_len( unsigned char **p,
53                          const unsigned char *end,
54                          int *len )
55 {
56     if( ( end - *p ) < 1 )
57         return( POLARSSL_ERR_ASN1_OUT_OF_DATA );
58
59     if( ( **p & 0x80 ) == 0 )
60         *len = *(*p)++;
61     else
62     {
63         switch( **p & 0x7F )
64         {
65         case 1:
66             if( ( end - *p ) < 2 )
67                 return( POLARSSL_ERR_ASN1_OUT_OF_DATA );
68
69             *len = (*p)[1];
70             (*p) += 2;
71             break;
72
73         case 2:
74             if( ( end - *p ) < 3 )
75                 return( POLARSSL_ERR_ASN1_OUT_OF_DATA );
76
77             *len = ( (*p)[1] << 8 ) | (*p)[2];
78             (*p) += 3;
79             break;
80
81         default:
82             return( POLARSSL_ERR_ASN1_INVALID_LENGTH );
83             break;
84         }
85     }
86
87     if( *len > (int) ( end - *p ) )
88         return( POLARSSL_ERR_ASN1_OUT_OF_DATA );
89
90     return( 0 );
91 }
92
93 /* This function is not exported by PolarSSL 0.14.2
94  * static */
95 int asn1_get_tag( unsigned char **p,
96                          const unsigned char *end,
97                          int *len, int tag )
98 {
99     if( ( end - *p ) < 1 )
100         return( POLARSSL_ERR_ASN1_OUT_OF_DATA );
101
102     if( **p != tag )
103         return( POLARSSL_ERR_ASN1_UNEXPECTED_TAG );
104
105     (*p)++;
106
107     return( asn1_get_len( p, end, len ) );
108 }
109
110 /* This function is not exported by PolarSSL 0.14.2
111  * static */
112 int asn1_get_int( unsigned char **p,
113                          const unsigned char *end,
114                          int *val )
115 {
116     int ret, len;
117
118     if( ( ret = asn1_get_tag( p, end, &len, ASN1_INTEGER ) ) != 0 )
119         return( ret );
120
121     if( len > (int) sizeof( int ) || ( **p & 0x80 ) != 0 )
122         return( POLARSSL_ERR_ASN1_INVALID_LENGTH );
123
124     *val = 0;
125
126     while( len-- > 0 )
127     {
128         *val = ( *val << 8 ) | **p;
129         (*p)++;
130     }
131
132     return( 0 );
133 }
134
135 /* This function is not exported by PolarSSL 0.14.2
136  * static */
137 int asn1_get_mpi( unsigned char **p,
138                          const unsigned char *end,
139                          mpi *X )
140 {
141     int ret, len;
142
143     if( ( ret = asn1_get_tag( p, end, &len, ASN1_INTEGER ) ) != 0 )
144         return( ret );
145
146     ret = mpi_read_binary( X, *p, len );
147
148     *p += len;
149
150     return( ret );
151 }
152 /* ***************   end copy from x509parse.c ********************/
153 #endif