Parse RSA private keys from PKCS#8 encoded blobs.
[strongswan.git] / src / libstrongswan / plugins / pkcs8 / pkcs8_builder.c
1 /*
2 * Copyright (C) 2012 Tobias Brunner
3 * Hochschule fuer Technik Rapperswil
4 *
5 * This program is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License as published by the
7 * Free Software Foundation; either version 2 of the License, or (at your
8 * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
9 *
10 * This program is distributed in the hope that it will be useful, but
11 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
12 * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
13 * for more details.
14 */
15
16 #include "pkcs8_builder.h"
17
18 #include <debug.h>
19 #include <asn1/oid.h>
20 #include <asn1/asn1.h>
21 #include <asn1/asn1_parser.h>
22 #include <credentials/keys/private_key.h>
23
24 /**
25 * ASN.1 definition of a privateKeyInfo structure
26 */
27 static const asn1Object_t pkinfoObjects[] = {
28 { 0, "privateKeyInfo", ASN1_SEQUENCE, ASN1_NONE }, /* 0 */
29 { 1, "version", ASN1_INTEGER, ASN1_BODY }, /* 1 */
30 { 1, "privateKeyAlgorithm", ASN1_EOC, ASN1_RAW }, /* 2 */
31 { 1, "privateKey", ASN1_OCTET_STRING, ASN1_BODY }, /* 3 */
32 { 1, "attributes", ASN1_CONTEXT_C_0, ASN1_OPT }, /* 4 */
33 { 1, "end opt", ASN1_EOC, ASN1_END }, /* 5 */
34 { 0, "exit", ASN1_EOC, ASN1_EXIT }
35 };
36 #define PKINFO_PRIVATE_KEY_ALGORITHM 2
37 #define PKINFO_PRIVATE_KEY 3
38
39 /**
40 * Load a generic private key from an ASN.1 encoded blob
41 */
42 static private_key_t *parse_private_key(chunk_t blob)
43 {
44 asn1_parser_t *parser;
45 chunk_t object;
46 int objectID;
47 private_key_t *key = NULL;
48 key_type_t type = KEY_ANY;
49
50 parser = asn1_parser_create(pkinfoObjects, blob);
51 parser->set_flags(parser, FALSE, TRUE);
52
53 while (parser->iterate(parser, &objectID, &object))
54 {
55 switch (objectID)
56 {
57 case PKINFO_PRIVATE_KEY_ALGORITHM:
58 {
59 int oid = asn1_parse_algorithmIdentifier(object,
60 parser->get_level(parser) + 1, NULL);
61
62 if (oid == OID_RSA_ENCRYPTION)
63 {
64 type = KEY_RSA;
65 }
66 else
67 { /* key type not supported */
68 goto end;
69 }
70 break;
71 }
72 case PKINFO_PRIVATE_KEY:
73 {
74 DBG2(DBG_ASN, "-- > --");
75 key = lib->creds->create(lib->creds, CRED_PRIVATE_KEY, type,
76 BUILD_BLOB_ASN1_DER, object, BUILD_END);
77 DBG2(DBG_ASN, "-- < --");
78 break;
79 }
80 }
81 }
82
83 end:
84 parser->destroy(parser);
85 return key;
86 }
87
88 /**
89 * See header.
90 */
91 private_key_t *pkcs8_private_key_load(key_type_t type, va_list args)
92 {
93 chunk_t blob = chunk_empty;
94
95 while (TRUE)
96 {
97 switch (va_arg(args, builder_part_t))
98 {
99 case BUILD_BLOB_ASN1_DER:
100 blob = va_arg(args, chunk_t);
101 continue;
102 case BUILD_END:
103 break;
104 default:
105 return NULL;
106 }
107 break;
108 }
109 return parse_private_key(blob);
110 }
111