2 * Copyright (C) 2008-2009 Martin Willi
3 * Copyright (C) 2008 Tobias Brunner
4 * Copyright (C) 2000-2008 Andreas Steffen
5 * Hochschule fuer Technik Rapperswil
7 * This program is free software; you can redistribute it and/or modify it
8 * under the terms of the GNU General Public License as published by the
9 * Free Software Foundation; either version 2 of the License, or (at your
10 * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
12 * This program is distributed in the hope that it will be useful, but
13 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
14 * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
18 #include "pkcs1_builder.h"
20 #include <utils/debug.h>
22 #include <asn1/asn1.h>
23 #include <asn1/asn1_parser.h>
24 #include <credentials/keys/private_key.h>
27 * ASN.1 definition of a subjectPublicKeyInfo structure
29 static const asn1Object_t pkinfoObjects
[] = {
30 { 0, "subjectPublicKeyInfo",ASN1_SEQUENCE
, ASN1_NONE
}, /* 0 */
31 { 1, "algorithm", ASN1_EOC
, ASN1_RAW
}, /* 1 */
32 { 1, "subjectPublicKey", ASN1_BIT_STRING
, ASN1_BODY
}, /* 2 */
33 { 0, "exit", ASN1_EOC
, ASN1_EXIT
}
35 #define PKINFO_SUBJECT_PUBLIC_KEY_ALGORITHM 1
36 #define PKINFO_SUBJECT_PUBLIC_KEY 2
39 * Load a generic public key from an ASN.1 encoded blob
41 static public_key_t
*parse_public_key(chunk_t blob
)
43 asn1_parser_t
*parser
;
46 public_key_t
*key
= NULL
;
47 key_type_t type
= KEY_ANY
;
49 parser
= asn1_parser_create(pkinfoObjects
, blob
);
51 while (parser
->iterate(parser
, &objectID
, &object
))
55 case PKINFO_SUBJECT_PUBLIC_KEY_ALGORITHM
:
57 int oid
= asn1_parse_algorithmIdentifier(object
,
58 parser
->get_level(parser
)+1, NULL
);
60 if (oid
== OID_RSA_ENCRYPTION
|| oid
== OID_RSAES_OAEP
)
64 else if (oid
== OID_EC_PUBLICKEY
)
66 /* we need the whole subjectPublicKeyInfo for EC public keys */
67 key
= lib
->creds
->create(lib
->creds
, CRED_PUBLIC_KEY
,
68 KEY_ECDSA
, BUILD_BLOB_ASN1_DER
, blob
, BUILD_END
);
73 /* key type not supported */
78 case PKINFO_SUBJECT_PUBLIC_KEY
:
79 if (object
.len
> 0 && *object
.ptr
== 0x00)
81 /* skip initial bit string octet defining 0 unused bits */
82 object
= chunk_skip(object
, 1);
84 DBG2(DBG_ASN
, "-- > --");
85 key
= lib
->creds
->create(lib
->creds
, CRED_PUBLIC_KEY
, type
,
86 BUILD_BLOB_ASN1_DER
, object
, BUILD_END
);
87 DBG2(DBG_ASN
, "-- < --");
93 parser
->destroy(parser
);
98 * ASN.1 definition of RSApublicKey
100 static const asn1Object_t pubkeyObjects
[] = {
101 { 0, "RSAPublicKey", ASN1_SEQUENCE
, ASN1_OBJ
}, /* 0 */
102 { 1, "modulus", ASN1_INTEGER
, ASN1_BODY
}, /* 1 */
103 { 1, "publicExponent", ASN1_INTEGER
, ASN1_BODY
}, /* 2 */
104 { 0, "exit", ASN1_EOC
, ASN1_EXIT
}
106 #define PUB_KEY_RSA_PUBLIC_KEY 0
107 #define PUB_KEY_MODULUS 1
108 #define PUB_KEY_EXPONENT 2
111 * Load a RSA public key from an ASN.1 encoded blob.
113 static public_key_t
*parse_rsa_public_key(chunk_t blob
)
116 asn1_parser_t
*parser
;
119 bool success
= FALSE
;
121 parser
= asn1_parser_create(pubkeyObjects
, blob
);
123 while (parser
->iterate(parser
, &objectID
, &object
))
127 case PUB_KEY_MODULUS
:
130 case PUB_KEY_EXPONENT
:
135 success
= parser
->success(parser
);
136 parser
->destroy(parser
);
142 return lib
->creds
->create(lib
->creds
, CRED_PUBLIC_KEY
, KEY_RSA
,
143 BUILD_RSA_MODULUS
, n
, BUILD_RSA_PUB_EXP
, e
, BUILD_END
);
147 * ASN.1 definition of a PKCS#1 RSA private key
149 static const asn1Object_t privkeyObjects
[] = {
150 { 0, "RSAPrivateKey", ASN1_SEQUENCE
, ASN1_NONE
}, /* 0 */
151 { 1, "version", ASN1_INTEGER
, ASN1_BODY
}, /* 1 */
152 { 1, "modulus", ASN1_INTEGER
, ASN1_BODY
}, /* 2 */
153 { 1, "publicExponent", ASN1_INTEGER
, ASN1_BODY
}, /* 3 */
154 { 1, "privateExponent", ASN1_INTEGER
, ASN1_BODY
}, /* 4 */
155 { 1, "prime1", ASN1_INTEGER
, ASN1_BODY
}, /* 5 */
156 { 1, "prime2", ASN1_INTEGER
, ASN1_BODY
}, /* 6 */
157 { 1, "exponent1", ASN1_INTEGER
, ASN1_BODY
}, /* 7 */
158 { 1, "exponent2", ASN1_INTEGER
, ASN1_BODY
}, /* 8 */
159 { 1, "coefficient", ASN1_INTEGER
, ASN1_BODY
}, /* 9 */
160 { 1, "otherPrimeInfos", ASN1_SEQUENCE
, ASN1_OPT
|
161 ASN1_LOOP
}, /* 10 */
162 { 2, "otherPrimeInfo", ASN1_SEQUENCE
, ASN1_NONE
}, /* 11 */
163 { 3, "prime", ASN1_INTEGER
, ASN1_BODY
}, /* 12 */
164 { 3, "exponent", ASN1_INTEGER
, ASN1_BODY
}, /* 13 */
165 { 3, "coefficient", ASN1_INTEGER
, ASN1_BODY
}, /* 14 */
166 { 1, "end opt or loop", ASN1_EOC
, ASN1_END
}, /* 15 */
167 { 0, "exit", ASN1_EOC
, ASN1_EXIT
}
169 #define PRIV_KEY_VERSION 1
170 #define PRIV_KEY_MODULUS 2
171 #define PRIV_KEY_PUB_EXP 3
172 #define PRIV_KEY_PRIV_EXP 4
173 #define PRIV_KEY_PRIME1 5
174 #define PRIV_KEY_PRIME2 6
175 #define PRIV_KEY_EXP1 7
176 #define PRIV_KEY_EXP2 8
177 #define PRIV_KEY_COEFF 9
180 * Load a RSA private key from a ASN1 encoded blob.
182 static private_key_t
*parse_rsa_private_key(chunk_t blob
)
184 chunk_t n
, e
, d
, p
, q
, exp1
, exp2
, coeff
;
185 asn1_parser_t
*parser
;
188 bool success
= FALSE
;
190 parser
= asn1_parser_create(privkeyObjects
, blob
);
191 parser
->set_flags(parser
, FALSE
, TRUE
);
193 while (parser
->iterate(parser
, &objectID
, &object
))
197 case PRIV_KEY_VERSION
:
198 if (object
.len
> 0 && *object
.ptr
!= 0)
200 DBG1(DBG_ASN
, "PKCS#1 private key format is not version 1");
204 case PRIV_KEY_MODULUS
:
207 case PRIV_KEY_PUB_EXP
:
210 case PRIV_KEY_PRIV_EXP
:
213 case PRIV_KEY_PRIME1
:
216 case PRIV_KEY_PRIME2
:
230 success
= parser
->success(parser
);
233 parser
->destroy(parser
);
238 return lib
->creds
->create(lib
->creds
, CRED_PRIVATE_KEY
, KEY_RSA
,
239 BUILD_RSA_MODULUS
, n
, BUILD_RSA_PUB_EXP
, e
, BUILD_RSA_PRIV_EXP
, d
,
240 BUILD_RSA_PRIME1
, p
, BUILD_RSA_PRIME2
, q
, BUILD_RSA_EXP1
, exp1
,
241 BUILD_RSA_EXP2
, exp2
, BUILD_RSA_COEFF
, coeff
, BUILD_END
);
247 public_key_t
*pkcs1_public_key_load(key_type_t type
, va_list args
)
249 chunk_t blob
= chunk_empty
;
253 switch (va_arg(args
, builder_part_t
))
255 case BUILD_BLOB_ASN1_DER
:
256 blob
= va_arg(args
, chunk_t
);
268 return parse_public_key(blob
);
270 return parse_rsa_public_key(blob
);
279 private_key_t
*pkcs1_private_key_load(key_type_t type
, va_list args
)
281 chunk_t blob
= chunk_empty
;
285 switch (va_arg(args
, builder_part_t
))
287 case BUILD_BLOB_ASN1_DER
:
288 blob
= va_arg(args
, chunk_t
);
297 return parse_rsa_private_key(blob
);