botan: Add support for Ed25519 keys
[strongswan.git] / src / libstrongswan / plugins / botan / botan_ed_public_key.c
1 /*
2 * Copyright (C) 2018 Tobias Brunner
3 * HSR Hochschule fuer Technik Rapperswil
4 *
5 * Permission is hereby granted, free of charge, to any person obtaining a copy
6 * of this software and associated documentation files (the "Software"), to deal
7 * in the Software without restriction, including without limitation the rights
8 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 * copies of the Software, and to permit persons to whom the Software is
10 * furnished to do so, subject to the following conditions:
11 *
12 * The above copyright notice and this permission notice shall be included in
13 * all copies or substantial portions of the Software.
14 *
15 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
21 * THE SOFTWARE.
22 */
23
24 #include "botan_ed_public_key.h"
25 #include "botan_util.h"
26
27 #include <botan/build.h>
28
29 #ifdef BOTAN_HAS_ED25519
30
31 #include <utils/debug.h>
32
33 typedef struct private_public_key_t private_public_key_t;
34
35 /**
36 * Private data
37 */
38 struct private_public_key_t {
39
40 /**
41 * Public interface
42 */
43 public_key_t public;
44
45 /**
46 * Botan public key object
47 */
48 botan_pubkey_t key;
49
50 /**
51 * Reference counter
52 */
53 refcount_t ref;
54 };
55
56 METHOD(public_key_t, get_type, key_type_t,
57 private_public_key_t *this)
58 {
59 return KEY_ED25519;
60 }
61
62 METHOD(public_key_t, get_keysize, int,
63 private_public_key_t *this)
64 {
65 return ED25519_KEY_LEN * 8;
66 }
67
68 METHOD(public_key_t, verify, bool,
69 private_public_key_t *this, signature_scheme_t scheme,
70 void *params, chunk_t data, chunk_t signature)
71 {
72 switch (scheme)
73 {
74 case SIGN_ED25519:
75 return botan_verify_signature(this->key, "Pure", data, signature);
76 default:
77 DBG1(DBG_LIB, "signature scheme %N not supported via botan",
78 signature_scheme_names, scheme);
79 return FALSE;
80 }
81 }
82
83 METHOD(public_key_t, encrypt, bool,
84 private_public_key_t *this, encryption_scheme_t scheme,
85 chunk_t crypto, chunk_t *plain)
86 {
87 DBG1(DBG_LIB, "EdDSA public key encryption not implemented");
88 return FALSE;
89 }
90
91 METHOD(public_key_t, get_fingerprint, bool,
92 private_public_key_t *this, cred_encoding_type_t type,
93 chunk_t *fingerprint)
94 {
95 return botan_get_fingerprint(this->key, this, type, fingerprint);
96 }
97
98 METHOD(public_key_t, get_encoding, bool,
99 private_public_key_t *this, cred_encoding_type_t type,
100 chunk_t *encoding)
101 {
102 return botan_get_encoding(this->key, type, encoding);
103 }
104
105 METHOD(public_key_t, get_ref, public_key_t*,
106 private_public_key_t *this)
107 {
108 ref_get(&this->ref);
109 return &this->public;
110 }
111
112 METHOD(public_key_t, destroy, void,
113 private_public_key_t *this)
114 {
115 if (ref_put(&this->ref))
116 {
117 lib->encoding->clear_cache(lib->encoding, this);
118 botan_pubkey_destroy(this->key);
119 free(this);
120 }
121 }
122
123 /**
124 * Internal generic constructor
125 */
126 static private_public_key_t *create_empty()
127 {
128 private_public_key_t *this;
129
130 INIT(this,
131 .public = {
132 .get_type = _get_type,
133 .verify = _verify,
134 .encrypt = _encrypt,
135 .get_keysize = _get_keysize,
136 .equals = public_key_equals,
137 .get_fingerprint = _get_fingerprint,
138 .has_fingerprint = public_key_has_fingerprint,
139 .get_encoding = _get_encoding,
140 .get_ref = _get_ref,
141 .destroy = _destroy,
142 },
143 .ref = 1,
144 );
145
146 return this;
147 }
148
149 /*
150 * Described in header
151 */
152 public_key_t *botan_ed_public_key_adopt(botan_pubkey_t key)
153 {
154 private_public_key_t *this;
155
156 this = create_empty();
157 this->key = key;
158
159 return &this->public;
160 }
161
162 /*
163 * Described in header
164 */
165 public_key_t *botan_ed_public_key_load(key_type_t type, va_list args)
166 {
167 private_public_key_t *this;
168 chunk_t key = chunk_empty;
169
170 while (TRUE)
171 {
172 switch (va_arg(args, builder_part_t))
173 {
174 case BUILD_EDDSA_PUB:
175 key = va_arg(args, chunk_t);
176 continue;
177 case BUILD_END:
178 break;
179 default:
180 return NULL;
181 }
182 break;
183 }
184
185 /* ASN.1-encoded keys are handled generically, so we only handle the
186 * explicit case */
187 if (key.len != ED25519_KEY_LEN)
188 {
189 return NULL;
190 }
191
192 this = create_empty();
193
194 if (botan_pubkey_load_ed25519(&this->key, key.ptr))
195 {
196 free(this);
197 return NULL;
198 }
199 return &this->public;
200 }
201
202 #endif