]>
Commit | Line | Data |
---|---|---|
e773fe4c MW |
1 | /* |
2 | * Copyright (C) 2009 Martin Willi | |
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 "pkcs1_encoder.h" | |
17 | ||
f05b4272 | 18 | #include <utils/debug.h> |
e773fe4c MW |
19 | #include <asn1/asn1.h> |
20 | #include <asn1/oid.h> | |
21 | ||
22 | /** | |
09fe3c7e | 23 | * Encode a public key in PKCS#1/ASN.1 DER |
e773fe4c | 24 | */ |
09fe3c7e | 25 | bool build_pub(chunk_t *encoding, va_list args) |
e773fe4c | 26 | { |
09fe3c7e | 27 | chunk_t n, e; |
7daf5226 | 28 | |
da9724e6 MW |
29 | if (cred_encoding_args(args, CRED_PART_RSA_MODULUS, &n, |
30 | CRED_PART_RSA_PUB_EXP, &e, CRED_PART_END)) | |
e773fe4c | 31 | { |
09fe3c7e MW |
32 | *encoding = asn1_wrap(ASN1_SEQUENCE, "mm", |
33 | asn1_wrap(ASN1_INTEGER, "c", n), | |
34 | asn1_wrap(ASN1_INTEGER, "c", e)); | |
35 | return TRUE; | |
e773fe4c | 36 | } |
09fe3c7e | 37 | return FALSE; |
e773fe4c MW |
38 | } |
39 | ||
40 | /** | |
09fe3c7e | 41 | * Encode a public key in PKCS#1/ASN.1 DER, contained in subjectPublicKeyInfo |
e773fe4c | 42 | */ |
09fe3c7e | 43 | bool build_pub_info(chunk_t *encoding, va_list args) |
e773fe4c MW |
44 | { |
45 | chunk_t n, e; | |
7daf5226 | 46 | |
da9724e6 MW |
47 | if (cred_encoding_args(args, CRED_PART_RSA_MODULUS, &n, |
48 | CRED_PART_RSA_PUB_EXP, &e, CRED_PART_END)) | |
e773fe4c | 49 | { |
caf1af1d | 50 | *encoding = asn1_wrap(ASN1_SEQUENCE, "mm", |
09fe3c7e MW |
51 | asn1_algorithmIdentifier(OID_RSA_ENCRYPTION), |
52 | asn1_bitstring("m", | |
53 | asn1_wrap(ASN1_SEQUENCE, "mm", | |
54 | asn1_wrap(ASN1_INTEGER, "c", n), | |
55 | asn1_wrap(ASN1_INTEGER, "c", e)))); | |
e773fe4c MW |
56 | return TRUE; |
57 | } | |
58 | return FALSE; | |
59 | } | |
60 | ||
61 | /** | |
62 | * Encode a private key in PKCS#1/ASN.1 DER | |
63 | */ | |
64 | bool build_priv(chunk_t *encoding, va_list args) | |
65 | { | |
66 | chunk_t n, e, d, p, q, exp1, exp2, coeff; | |
7daf5226 | 67 | |
da9724e6 MW |
68 | if (cred_encoding_args(args, CRED_PART_RSA_MODULUS, &n, |
69 | CRED_PART_RSA_PUB_EXP, &e, CRED_PART_RSA_PRIV_EXP, &d, | |
70 | CRED_PART_RSA_PRIME1, &p, CRED_PART_RSA_PRIME2, &q, | |
71 | CRED_PART_RSA_EXP1, &exp1, CRED_PART_RSA_EXP2, &exp2, | |
72 | CRED_PART_RSA_COEFF, &coeff, CRED_PART_END)) | |
e773fe4c MW |
73 | { |
74 | *encoding = asn1_wrap(ASN1_SEQUENCE, "cmmssssss", | |
75 | ASN1_INTEGER_0, | |
76 | asn1_wrap(ASN1_INTEGER, "c", n), | |
77 | asn1_wrap(ASN1_INTEGER, "c", e), | |
78 | asn1_wrap(ASN1_INTEGER, "c", d), | |
79 | asn1_wrap(ASN1_INTEGER, "c", p), | |
80 | asn1_wrap(ASN1_INTEGER, "c", q), | |
81 | asn1_wrap(ASN1_INTEGER, "c", exp1), | |
82 | asn1_wrap(ASN1_INTEGER, "c", exp2), | |
83 | asn1_wrap(ASN1_INTEGER, "c", coeff)); | |
84 | return TRUE; | |
85 | } | |
86 | return FALSE; | |
87 | } | |
88 | ||
09fe3c7e MW |
89 | /** |
90 | * Build the SHA1 hash of pubkey(info) ASN.1 data | |
91 | */ | |
92 | static bool hash_pubkey(chunk_t pubkey, chunk_t *hash) | |
93 | { | |
94 | hasher_t *hasher; | |
7daf5226 | 95 | |
09fe3c7e | 96 | hasher = lib->crypto->create_hasher(lib->crypto, HASH_SHA1); |
87dd205b | 97 | if (!hasher || !hasher->allocate_hash(hasher, pubkey, hash)) |
09fe3c7e | 98 | { |
87dd205b | 99 | DESTROY_IF(hasher); |
09fe3c7e | 100 | chunk_free(&pubkey); |
8b0e0910 TB |
101 | DBG1(DBG_LIB, "SHA1 hash algorithm not supported, " |
102 | "fingerprinting failed"); | |
09fe3c7e MW |
103 | return FALSE; |
104 | } | |
09fe3c7e MW |
105 | hasher->destroy(hasher); |
106 | chunk_free(&pubkey); | |
107 | return TRUE; | |
108 | } | |
109 | ||
110 | /** | |
111 | * build the fingerprint of the subjectPublicKeyInfo object | |
112 | */ | |
113 | static bool build_info_sha1(chunk_t *encoding, va_list args) | |
114 | { | |
115 | chunk_t pubkey; | |
7daf5226 | 116 | |
09fe3c7e MW |
117 | if (build_pub_info(&pubkey, args)) |
118 | { | |
119 | return hash_pubkey(pubkey, encoding); | |
120 | } | |
121 | return FALSE; | |
122 | } | |
123 | ||
124 | /** | |
125 | * build the fingerprint of the subjectPublicKey object | |
126 | */ | |
127 | static bool build_sha1(chunk_t *encoding, va_list args) | |
128 | { | |
129 | chunk_t pubkey; | |
7daf5226 | 130 | |
09fe3c7e MW |
131 | if (build_pub(&pubkey, args)) |
132 | { | |
133 | return hash_pubkey(pubkey, encoding); | |
134 | } | |
135 | return FALSE; | |
136 | } | |
137 | ||
e773fe4c MW |
138 | /** |
139 | * See header. | |
140 | */ | |
da9724e6 | 141 | bool pkcs1_encoder_encode(cred_encoding_type_t type, chunk_t *encoding, |
e773fe4c MW |
142 | va_list args) |
143 | { | |
144 | switch (type) | |
145 | { | |
da9724e6 | 146 | case KEYID_PUBKEY_INFO_SHA1: |
e773fe4c | 147 | return build_info_sha1(encoding, args); |
da9724e6 | 148 | case KEYID_PUBKEY_SHA1: |
e773fe4c | 149 | return build_sha1(encoding, args); |
da9724e6 | 150 | case PUBKEY_ASN1_DER: |
e773fe4c | 151 | return build_pub(encoding, args); |
da9724e6 | 152 | case PUBKEY_SPKI_ASN1_DER: |
09fe3c7e | 153 | return build_pub_info(encoding, args); |
da9724e6 | 154 | case PRIVKEY_ASN1_DER: |
e773fe4c MW |
155 | return build_priv(encoding, args); |
156 | default: | |
157 | return FALSE; | |
158 | } | |
159 | } | |
160 | ||
161 |