|
Lines 31-36
Link Here
|
| 31 |
#include <errno.h> |
31 |
#include <errno.h> |
| 32 |
|
32 |
|
| 33 |
#include <openssl/rsa.h> |
33 |
#include <openssl/rsa.h> |
|
|
34 |
#ifdef OPENSSL_HAS_ECC |
| 35 |
#include <openssl/ecdsa.h> |
| 36 |
#if ((defined(LIBRESSL_VERSION_NUMBER) && \ |
| 37 |
(LIBRESSL_VERSION_NUMBER >= 0x20010002L))) || \ |
| 38 |
(defined(ECDSA_F_ECDSA_METHOD_NEW)) |
| 39 |
#define ENABLE_PKCS11_ECDSA 1 |
| 40 |
#endif |
| 41 |
#endif |
| 34 |
|
42 |
|
| 35 |
#include "pathnames.h" |
43 |
#include "pathnames.h" |
| 36 |
#include "xmalloc.h" |
44 |
#include "xmalloc.h" |
|
Lines 139-147
Link Here
|
| 139 |
return (ret); |
147 |
return (ret); |
| 140 |
} |
148 |
} |
| 141 |
|
149 |
|
| 142 |
/* redirect the private key encrypt operation to the ssh-pkcs11-helper */ |
150 |
/* redirect the RSA private key encrypt operation to the ssh-pkcs11-helper */ |
| 143 |
static int |
151 |
static int |
| 144 |
wrap_key(RSA *rsa) |
152 |
wrap_rsa_key(RSA *rsa) |
| 145 |
{ |
153 |
{ |
| 146 |
static RSA_METHOD helper_rsa; |
154 |
static RSA_METHOD helper_rsa; |
| 147 |
|
155 |
|
|
Lines 152-157
Link Here
|
| 152 |
return (0); |
160 |
return (0); |
| 153 |
} |
161 |
} |
| 154 |
|
162 |
|
|
|
163 |
#ifdef ENABLE_PKCS11_ECDSA |
| 164 |
static ECDSA_SIG * |
| 165 |
pkcs11_ecdsa_private_sign(const unsigned char *from, int flen, |
| 166 |
const BIGNUM *inv, const BIGNUM *r, EC_KEY * ecdsa) |
| 167 |
{ |
| 168 |
Key key; |
| 169 |
u_char *blob, *signature = NULL; |
| 170 |
u_int blen, slen = 0; |
| 171 |
Buffer msg; |
| 172 |
ECDSA_SIG *ret = NULL; |
| 173 |
|
| 174 |
key.type = KEY_ECDSA; |
| 175 |
key.ecdsa = ecdsa; |
| 176 |
key.ecdsa_nid = sshkey_ecdsa_key_to_nid(ecdsa); |
| 177 |
if (key_to_blob(&key, &blob, &blen) == 0) |
| 178 |
return NULL; |
| 179 |
buffer_init(&msg); |
| 180 |
buffer_put_char(&msg, SSH2_AGENTC_SIGN_REQUEST); |
| 181 |
buffer_put_string(&msg, blob, blen); |
| 182 |
buffer_put_string(&msg, from, flen); |
| 183 |
buffer_put_int(&msg, 0); |
| 184 |
free(blob); |
| 185 |
send_msg(&msg); |
| 186 |
buffer_clear(&msg); |
| 187 |
|
| 188 |
if (recv_msg(&msg) == SSH2_AGENT_SIGN_RESPONSE) { |
| 189 |
signature = buffer_get_string(&msg, &slen); |
| 190 |
if (slen <= (u_int)ECDSA_size(ecdsa)) { |
| 191 |
int nlen = slen / 2; |
| 192 |
ret = ECDSA_SIG_new(); |
| 193 |
BN_bin2bn(&signature[0], nlen, ret->r); |
| 194 |
BN_bin2bn(&signature[nlen], nlen, ret->s); |
| 195 |
} |
| 196 |
free(signature); |
| 197 |
} |
| 198 |
buffer_free(&msg); |
| 199 |
return (ret); |
| 200 |
} |
| 201 |
|
| 202 |
/* redirect the ECDSA private key encrypt operation to the ssh-pkcs11-helper */ |
| 203 |
static int |
| 204 |
wrap_ecdsa_key(EC_KEY *ecdsa) { |
| 205 |
static ECDSA_METHOD *helper_ecdsa = NULL; |
| 206 |
if(helper_ecdsa == NULL) { |
| 207 |
const ECDSA_METHOD *def = ECDSA_get_default_method(); |
| 208 |
#ifdef ECDSA_F_ECDSA_METHOD_NEW |
| 209 |
helper_ecdsa = ECDSA_METHOD_new((ECDSA_METHOD *)def); |
| 210 |
ECDSA_METHOD_set_name(helper_ecdsa, "ssh-pkcs11-helper-ecdsa"); |
| 211 |
ECDSA_METHOD_set_sign(helper_ecdsa, pkcs11_ecdsa_private_sign); |
| 212 |
#else |
| 213 |
helper_ecdsa = xcalloc(1, sizeof(*helper_ecdsa)); |
| 214 |
memcpy(helper_ecdsa, def, sizeof(*helper_ecdsa)); |
| 215 |
helper_ecdsa->name = "ssh-pkcs11-helper-ecdsa"; |
| 216 |
helper_ecdsa->ecdsa_do_sign = pkcs11_ecdsa_private_sign; |
| 217 |
#endif |
| 218 |
} |
| 219 |
ECDSA_set_method(ecdsa, helper_ecdsa); |
| 220 |
return (0); |
| 221 |
} |
| 222 |
#endif |
| 223 |
|
| 155 |
static int |
224 |
static int |
| 156 |
pkcs11_start_helper(void) |
225 |
pkcs11_start_helper(void) |
| 157 |
{ |
226 |
{ |
|
Lines 209-215
Link Here
|
| 209 |
blob = buffer_get_string(&msg, &blen); |
278 |
blob = buffer_get_string(&msg, &blen); |
| 210 |
free(buffer_get_string(&msg, NULL)); |
279 |
free(buffer_get_string(&msg, NULL)); |
| 211 |
k = key_from_blob(blob, blen); |
280 |
k = key_from_blob(blob, blen); |
| 212 |
wrap_key(k->rsa); |
281 |
if(k->type == KEY_RSA) { |
|
|
282 |
wrap_rsa_key(k->rsa); |
| 283 |
#ifdef ENABLE_PKCS11_ECDSA |
| 284 |
} else if(k->type == KEY_ECDSA) { |
| 285 |
wrap_ecdsa_key(k->ecdsa); |
| 286 |
#endif /* ENABLE_PKCS11_ECDSA */ |
| 287 |
} else { |
| 288 |
/* Unsupported type */ |
| 289 |
} |
| 213 |
(*keysp)[i] = k; |
290 |
(*keysp)[i] = k; |
| 214 |
free(blob); |
291 |
free(blob); |
| 215 |
} |
292 |
} |