PKCS#11: Support ECDSA keys and PKCS#11 URIs
Based on the patches in upstream bugzilla: ECDSA: https://bugzilla.mindrot.org/show_bug.cgi?id=2474 PKCS#11 URI: https://bugzilla.mindrot.org/show_bug.cgi?id=2817
This commit is contained in:
parent
3cd4899257
commit
7e9748a2b5
@ -2469,7 +2469,7 @@ diff -up openssh/ssh-pkcs11-client.c.openssl openssh/ssh-pkcs11-client.c
|
||||
+++ openssh/ssh-pkcs11-client.c 2017-09-26 13:19:31.803249734 +0200
|
||||
@@ -143,12 +143,16 @@ pkcs11_rsa_private_encrypt(int flen, con
|
||||
static int
|
||||
wrap_key(RSA *rsa)
|
||||
wrap_rsa_key(RSA *rsa)
|
||||
{
|
||||
- static RSA_METHOD helper_rsa;
|
||||
+ static RSA_METHOD *helper_rsa;
|
||||
@ -2493,25 +2493,25 @@ diff -up openssh/ssh-pkcs11.c.openssl openssh/ssh-pkcs11.c
|
||||
--- openssh/ssh-pkcs11.c.openssl 2017-09-19 06:26:43.000000000 +0200
|
||||
+++ openssh/ssh-pkcs11.c 2017-09-26 13:19:31.803249734 +0200
|
||||
@@ -67,7 +67,7 @@ struct pkcs11_key {
|
||||
struct pkcs11_provider *provider;
|
||||
CK_ULONG slotidx;
|
||||
CK_ULONG key_type;
|
||||
int (*orig_finish)(RSA *rsa);
|
||||
- RSA_METHOD rsa_method;
|
||||
+ RSA_METHOD *rsa_method;
|
||||
char *label;
|
||||
char *keyid;
|
||||
int keyid_len;
|
||||
};
|
||||
@@ -183,6 +183,7 @@ pkcs11_rsa_finish(RSA *rsa)
|
||||
if (k11->provider)
|
||||
pkcs11_provider_unref(k11->provider);
|
||||
free(k11->keyid);
|
||||
free(k11->label);
|
||||
+ RSA_meth_free(k11->rsa_method);
|
||||
free(k11);
|
||||
}
|
||||
return (rv);
|
||||
@@ -326,13 +326,21 @@ pkcs11_rsa_wrap(struct pkcs11_provider *
|
||||
k11->keyid = xmalloc(k11->keyid_len);
|
||||
memcpy(k11->keyid, keyid_attrib->pValue, k11->keyid_len);
|
||||
memcpy(k11->label, label_attrib->pValue, label_attrib->ulValueLen);
|
||||
k11->label[label_attrib->ulValueLen] = 0;
|
||||
}
|
||||
- k11->orig_finish = def->finish;
|
||||
- memcpy(&k11->rsa_method, def, sizeof(k11->rsa_method));
|
||||
@ -2550,14 +2550,14 @@ diff -up openssh/ssh-pkcs11.c.openssl openssh/ssh-pkcs11.c
|
||||
if ((rsa = RSA_new()) == NULL) {
|
||||
error("RSA_new failed");
|
||||
} else {
|
||||
- rsa->n = BN_bin2bn(attribs[1].pValue,
|
||||
- rsa->n = BN_bin2bn(attribs[2].pValue,
|
||||
+ BIGNUM *rsa_n, *rsa_e;
|
||||
+
|
||||
+ rsa_n = BN_bin2bn(attribs[1].pValue,
|
||||
attribs[1].ulValueLen, NULL);
|
||||
- rsa->e = BN_bin2bn(attribs[2].pValue,
|
||||
+ rsa_e = BN_bin2bn(attribs[2].pValue,
|
||||
+ rsa_n = BN_bin2bn(attribs[2].pValue,
|
||||
attribs[2].ulValueLen, NULL);
|
||||
- rsa->e = BN_bin2bn(attribs[3].pValue,
|
||||
+ rsa_e = BN_bin2bn(attribs[3].pValue,
|
||||
attribs[3].ulValueLen, NULL);
|
||||
+ if (rsa_n == NULL || rsa_e == NULL)
|
||||
+ error("BN_bin2bn failed");
|
||||
+ if (RSA_set0_key(rsa, rsa_n, rsa_e, NULL) == 0)
|
||||
@ -2581,11 +2581,13 @@ diff -up openssh/ssh-pkcs11.c.openssl openssh/ssh-pkcs11.c
|
||||
}
|
||||
X509_free(x509);
|
||||
}
|
||||
key = NULL;
|
||||
if (rsa || ecdsa) {
|
||||
- if (rsa && rsa->n && rsa->e &&
|
||||
+ if (rsa)
|
||||
+ RSA_get0_key(rsa, &n, &e, NULL);
|
||||
+ if (rsa && n && e &&
|
||||
pkcs11_rsa_wrap(p, slotidx, &attribs[0], rsa) == 0) {
|
||||
pkcs11_rsa_wrap(p, slotidx, &attribs[0], &attribs[1], rsa) == 0) {
|
||||
if ((key = sshkey_new(KEY_UNSPEC)) == NULL)
|
||||
fatal("sshkey_new failed");
|
||||
diff -up openssh/ssh-rsa.c.openssl openssh/ssh-rsa.c
|
||||
|
752
openssh-7.6p1-pkcs11-ecdsa.patch
Normal file
752
openssh-7.6p1-pkcs11-ecdsa.patch
Normal file
@ -0,0 +1,752 @@
|
||||
diff -up openssh-7.6p1/ssh-pkcs11-client.c.pkcs11-ecdsa openssh-7.6p1/ssh-pkcs11-client.c
|
||||
--- openssh-7.6p1/ssh-pkcs11-client.c.pkcs11-ecdsa 2018-02-16 13:25:59.426469253 +0100
|
||||
+++ openssh-7.6p1/ssh-pkcs11-client.c 2018-02-16 13:25:59.428469265 +0100
|
||||
@@ -31,6 +31,15 @@
|
||||
#include <errno.h>
|
||||
|
||||
#include <openssl/rsa.h>
|
||||
+#ifdef OPENSSL_HAS_ECC
|
||||
+#include <openssl/ecdsa.h>
|
||||
+#if ((defined(LIBRESSL_VERSION_NUMBER) && \
|
||||
+ (LIBRESSL_VERSION_NUMBER >= 0x20010002L))) || \
|
||||
+ (defined(ECDSA_F_ECDSA_METHOD_NEW)) || \
|
||||
+ (OPENSSL_VERSION_NUMBER >= 0x00010100L)
|
||||
+#define ENABLE_PKCS11_ECDSA 1
|
||||
+#endif
|
||||
+#endif
|
||||
|
||||
#include "pathnames.h"
|
||||
#include "xmalloc.h"
|
||||
@@ -139,9 +147,9 @@ pkcs11_rsa_private_encrypt(int flen, con
|
||||
return (ret);
|
||||
}
|
||||
|
||||
-/* redirect the private key encrypt operation to the ssh-pkcs11-helper */
|
||||
+/* redirect the RSA private key encrypt operation to the ssh-pkcs11-helper */
|
||||
static int
|
||||
-wrap_key(RSA *rsa)
|
||||
+wrap_rsa_key(RSA *rsa)
|
||||
{
|
||||
static RSA_METHOD helper_rsa;
|
||||
|
||||
@@ -152,6 +160,81 @@ wrap_key(RSA *rsa)
|
||||
return (0);
|
||||
}
|
||||
|
||||
+#ifdef ENABLE_PKCS11_ECDSA
|
||||
+static ECDSA_SIG *
|
||||
+pkcs11_ecdsa_private_sign(const unsigned char *from, int flen,
|
||||
+ const BIGNUM *inv, const BIGNUM *rp, EC_KEY * ecdsa)
|
||||
+{
|
||||
+ Key key;
|
||||
+ u_char *blob, *signature = NULL;
|
||||
+ u_int blen, slen = 0;
|
||||
+ Buffer msg;
|
||||
+ ECDSA_SIG *ret = NULL;
|
||||
+ BIGNUM *r = NULL, *s = NULL;
|
||||
+
|
||||
+ key.type = KEY_ECDSA;
|
||||
+ key.ecdsa = ecdsa;
|
||||
+ key.ecdsa_nid = sshkey_ecdsa_key_to_nid(ecdsa);
|
||||
+ if (key_to_blob(&key, &blob, &blen) == 0)
|
||||
+ return NULL;
|
||||
+ buffer_init(&msg);
|
||||
+ buffer_put_char(&msg, SSH2_AGENTC_SIGN_REQUEST);
|
||||
+ buffer_put_string(&msg, blob, blen);
|
||||
+ buffer_put_string(&msg, from, flen);
|
||||
+ buffer_put_int(&msg, 0);
|
||||
+ free(blob);
|
||||
+ send_msg(&msg);
|
||||
+ buffer_clear(&msg);
|
||||
+
|
||||
+ if (recv_msg(&msg) == SSH2_AGENT_SIGN_RESPONSE) {
|
||||
+ signature = buffer_get_string(&msg, &slen);
|
||||
+ if (slen <= (u_int)ECDSA_size(ecdsa)) {
|
||||
+ int nlen = slen / 2;
|
||||
+ ret = ECDSA_SIG_new();
|
||||
+ r = BN_new();
|
||||
+ s = BN_new();
|
||||
+ BN_bin2bn(&signature[0], nlen, r);
|
||||
+ BN_bin2bn(&signature[nlen], nlen, s);
|
||||
+ ECDSA_SIG_set0(ret, r, s);
|
||||
+ }
|
||||
+ free(signature);
|
||||
+ }
|
||||
+ buffer_free(&msg);
|
||||
+ return (ret);
|
||||
+}
|
||||
+
|
||||
+/* redirect the ECDSA private key encrypt operation to the ssh-pkcs11-helper */
|
||||
+static int
|
||||
+wrap_ecdsa_key(EC_KEY *ecdsa) {
|
||||
+#if (OPENSSL_VERSION_NUMBER >= 0x00010100L)
|
||||
+ static EC_KEY_METHOD *helper_ecdsa = NULL;
|
||||
+ if (helper_ecdsa == NULL) {
|
||||
+ const EC_KEY_METHOD *def = EC_KEY_get_default_method();
|
||||
+ helper_ecdsa = EC_KEY_METHOD_new(def);
|
||||
+ EC_KEY_METHOD_set_sign(helper_ecdsa, NULL, NULL, pkcs11_ecdsa_private_sign);
|
||||
+ }
|
||||
+ EC_KEY_set_method(ecdsa, helper_ecdsa);
|
||||
+#else
|
||||
+ static ECDSA_METHOD *helper_ecdsa = NULL;
|
||||
+ if(helper_ecdsa == NULL) {
|
||||
+ const ECDSA_METHOD *def = ECDSA_get_default_method();
|
||||
+# ifdef ECDSA_F_ECDSA_METHOD_NEW
|
||||
+ helper_ecdsa = ECDSA_METHOD_new((ECDSA_METHOD *)def);
|
||||
+ ECDSA_METHOD_set_name(helper_ecdsa, "ssh-pkcs11-helper-ecdsa");
|
||||
+ ECDSA_METHOD_set_sign(helper_ecdsa, pkcs11_ecdsa_private_sign);
|
||||
+# else
|
||||
+ helper_ecdsa = xcalloc(1, sizeof(*helper_ecdsa));
|
||||
+ memcpy(helper_ecdsa, def, sizeof(*helper_ecdsa));
|
||||
+ helper_ecdsa->name = "ssh-pkcs11-helper-ecdsa";
|
||||
+ helper_ecdsa->ecdsa_do_sign = pkcs11_ecdsa_private_sign;
|
||||
+# endif
|
||||
+ }
|
||||
+ ECDSA_set_method(ecdsa, helper_ecdsa);
|
||||
+#endif
|
||||
+ return (0);
|
||||
+}
|
||||
+#endif
|
||||
+
|
||||
static int
|
||||
pkcs11_start_helper(void)
|
||||
{
|
||||
@@ -212,7 +281,15 @@ pkcs11_add_provider(char *name, char *pi
|
||||
blob = buffer_get_string(&msg, &blen);
|
||||
free(buffer_get_string(&msg, NULL));
|
||||
k = key_from_blob(blob, blen);
|
||||
- wrap_key(k->rsa);
|
||||
+ if(k->type == KEY_RSA) {
|
||||
+ wrap_rsa_key(k->rsa);
|
||||
+#ifdef ENABLE_PKCS11_ECDSA
|
||||
+ } else if(k->type == KEY_ECDSA) {
|
||||
+ wrap_ecdsa_key(k->ecdsa);
|
||||
+#endif /* ENABLE_PKCS11_ECDSA */
|
||||
+ } else {
|
||||
+ /* Unsupported type */
|
||||
+ }
|
||||
(*keysp)[i] = k;
|
||||
free(blob);
|
||||
}
|
||||
diff -up openssh-7.6p1/ssh-pkcs11.c.pkcs11-ecdsa openssh-7.6p1/ssh-pkcs11.c
|
||||
--- openssh-7.6p1/ssh-pkcs11.c.pkcs11-ecdsa 2018-02-16 13:25:59.427469259 +0100
|
||||
+++ openssh-7.6p1/ssh-pkcs11.c 2018-02-16 13:44:51.270554797 +0100
|
||||
@@ -32,6 +32,16 @@
|
||||
#include "openbsd-compat/sys-queue.h"
|
||||
|
||||
#include <openssl/x509.h>
|
||||
+#include <openssl/rsa.h>
|
||||
+#ifdef OPENSSL_HAS_ECC
|
||||
+#include <openssl/ecdsa.h>
|
||||
+#if ((defined(LIBRESSL_VERSION_NUMBER) && \
|
||||
+ (LIBRESSL_VERSION_NUMBER >= 0x20010002L))) || \
|
||||
+ (defined(ECDSA_F_ECDSA_METHOD_NEW)) || \
|
||||
+ (OPENSSL_VERSION_NUMBER >= 0x00010100L)
|
||||
+#define ENABLE_PKCS11_ECDSA 1
|
||||
+#endif
|
||||
+#endif
|
||||
|
||||
#define CRYPTOKI_COMPAT
|
||||
#include "pkcs11.h"
|
||||
@@ -67,6 +76,7 @@ TAILQ_HEAD(, pkcs11_provider) pkcs11_pro
|
||||
struct pkcs11_key {
|
||||
struct pkcs11_provider *provider;
|
||||
CK_ULONG slotidx;
|
||||
+ CK_ULONG key_type;
|
||||
int (*orig_finish)(RSA *rsa);
|
||||
RSA_METHOD rsa_method;
|
||||
char *label;
|
||||
@@ -75,6 +85,9 @@ struct pkcs11_key {
|
||||
};
|
||||
|
||||
int pkcs11_interactive = 0;
|
||||
+#ifdef ENABLE_PKCS11_ECDSA
|
||||
+static int pkcs11_key_idx = -1;
|
||||
+#endif /* ENABLE_PKCS11_ECDSA */
|
||||
|
||||
/*
|
||||
* This can't be in the ssh-pkcs11-uri, becase we can not depend on
|
||||
@@ -289,6 +302,40 @@ pkcs11_find(struct pkcs11_provider *p, C
|
||||
return (ret);
|
||||
}
|
||||
|
||||
+int pkcs11_login(struct pkcs11_key *k11, CK_FUNCTION_LIST *f, struct pkcs11_slotinfo *si) {
|
||||
+ char *pin = NULL, prompt[1024];
|
||||
+ CK_RV rv;
|
||||
+ if ((si->token.flags & CKF_LOGIN_REQUIRED) && !si->logged_in) {
|
||||
+ if (!pkcs11_interactive) {
|
||||
+ error("need pin entry%s", (si->token.flags &
|
||||
+ CKF_PROTECTED_AUTHENTICATION_PATH) ?
|
||||
+ " on reader keypad" : "");
|
||||
+ return (-1);
|
||||
+ }
|
||||
+ if (si->token.flags & CKF_PROTECTED_AUTHENTICATION_PATH)
|
||||
+ verbose("Deferring PIN entry to reader keypad.");
|
||||
+ else {
|
||||
+ snprintf(prompt, sizeof(prompt),
|
||||
+ "Enter PIN for '%s': ", si->token.label);
|
||||
+ pin = read_passphrase(prompt, RP_ALLOW_EOF);
|
||||
+ if (pin == NULL)
|
||||
+ return (-1); /* bail out */
|
||||
+ }
|
||||
+ rv = f->C_Login(si->session, CKU_USER, (u_char *)pin,
|
||||
+ (pin != NULL) ? strlen(pin) : 0);
|
||||
+ if (pin != NULL) {
|
||||
+ explicit_bzero(pin, strlen(pin));
|
||||
+ free(pin);
|
||||
+ }
|
||||
+ if (rv != CKR_OK && rv != CKR_USER_ALREADY_LOGGED_IN) {
|
||||
+ error("C_Login failed: %lu", rv);
|
||||
+ return (-1);
|
||||
+ }
|
||||
+ si->logged_in = 1;
|
||||
+ }
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
/* openssl callback doing the actual signing operation */
|
||||
static int
|
||||
pkcs11_rsa_private_encrypt(int flen, const u_char *from, u_char *to, RSA *rsa,
|
||||
@@ -310,7 +357,6 @@ pkcs11_rsa_private_encrypt(int flen, con
|
||||
{CKA_ID, NULL, 0},
|
||||
{CKA_SIGN, NULL, sizeof(true_val) }
|
||||
};
|
||||
- char *pin = NULL, prompt[1024];
|
||||
int rval = -1;
|
||||
|
||||
key_filter[0].pValue = &private_key_class;
|
||||
@@ -326,33 +372,8 @@ pkcs11_rsa_private_encrypt(int flen, con
|
||||
}
|
||||
f = k11->provider->function_list;
|
||||
si = &k11->provider->slotinfo[k11->slotidx];
|
||||
- if ((si->token.flags & CKF_LOGIN_REQUIRED) && !si->logged_in) {
|
||||
- if (!pkcs11_interactive) {
|
||||
- error("need pin entry%s", (si->token.flags &
|
||||
- CKF_PROTECTED_AUTHENTICATION_PATH) ?
|
||||
- " on reader keypad" : "");
|
||||
- return (-1);
|
||||
- }
|
||||
- if (si->token.flags & CKF_PROTECTED_AUTHENTICATION_PATH)
|
||||
- verbose("Deferring PIN entry to reader keypad.");
|
||||
- else {
|
||||
- snprintf(prompt, sizeof(prompt),
|
||||
- "Enter PIN for '%s': ", si->token.label);
|
||||
- pin = read_passphrase(prompt, RP_ALLOW_EOF);
|
||||
- if (pin == NULL)
|
||||
- return (-1); /* bail out */
|
||||
- }
|
||||
- rv = f->C_Login(si->session, CKU_USER, (u_char *)pin,
|
||||
- (pin != NULL) ? strlen(pin) : 0);
|
||||
- if (pin != NULL) {
|
||||
- explicit_bzero(pin, strlen(pin));
|
||||
- free(pin);
|
||||
- }
|
||||
- if (rv != CKR_OK && rv != CKR_USER_ALREADY_LOGGED_IN) {
|
||||
- error("C_Login failed: %lu", rv);
|
||||
- return (-1);
|
||||
- }
|
||||
- si->logged_in = 1;
|
||||
+ if(pkcs11_login(k11, f, si)) {
|
||||
+ return (-1);
|
||||
}
|
||||
key_filter[1].pValue = k11->keyid;
|
||||
key_filter[1].ulValueLen = k11->keyid_len;
|
||||
@@ -390,6 +411,7 @@ pkcs11_rsa_wrap(struct pkcs11_provider *
|
||||
const RSA_METHOD *def = RSA_get_default_method();
|
||||
|
||||
k11 = xcalloc(1, sizeof(*k11));
|
||||
+ k11->key_type = CKK_RSA;
|
||||
k11->provider = provider;
|
||||
provider->refcount++; /* provider referenced by RSA key */
|
||||
k11->slotidx = slotidx;
|
||||
@@ -415,6 +437,184 @@ pkcs11_rsa_wrap(struct pkcs11_provider *
|
||||
return (0);
|
||||
}
|
||||
|
||||
+#ifdef ENABLE_PKCS11_ECDSA
|
||||
+static ECDSA_SIG *pkcs11_ecdsa_sign(const unsigned char *dgst, int dgst_len,
|
||||
+ const BIGNUM *inv, const BIGNUM *rp,
|
||||
+ EC_KEY *ecdsa) {
|
||||
+ struct pkcs11_key *k11;
|
||||
+ struct pkcs11_slotinfo *si;
|
||||
+ CK_FUNCTION_LIST *f;
|
||||
+ CK_OBJECT_HANDLE obj;
|
||||
+ CK_ULONG tlen = 0;
|
||||
+ CK_RV rv;
|
||||
+ CK_OBJECT_CLASS private_key_class = CKO_PRIVATE_KEY;
|
||||
+ CK_BBOOL true_val = CK_TRUE;
|
||||
+ CK_MECHANISM mech = {
|
||||
+ CKM_ECDSA, NULL_PTR, 0
|
||||
+ };
|
||||
+ CK_ATTRIBUTE key_filter[] = {
|
||||
+ {CKA_CLASS, NULL, sizeof(private_key_class) },
|
||||
+ {CKA_ID, NULL, 0},
|
||||
+ {CKA_SIGN, NULL, sizeof(true_val) }
|
||||
+ };
|
||||
+ ECDSA_SIG *rval = NULL;
|
||||
+ key_filter[0].pValue = &private_key_class;
|
||||
+ key_filter[2].pValue = &true_val;
|
||||
+
|
||||
+ #if (OPENSSL_VERSION_NUMBER >= 0x00010100L)
|
||||
+ if ((k11 = (struct pkcs11_key *)EC_KEY_get_ex_data(ecdsa, pkcs11_key_idx)) == NULL) {
|
||||
+ error("EC_KEY_get_ex_data failed for ecdsa %p", ecdsa);
|
||||
+ #else
|
||||
+ if ((k11 = (struct pkcs11_key *)ECDSA_get_ex_data(ecdsa, pkcs11_key_idx)) == NULL) {
|
||||
+ error("ECDSA_get_ex_data failed for ecdsa %p", ecdsa);
|
||||
+ #endif
|
||||
+ return NULL;
|
||||
+ }
|
||||
+ if (!k11->provider || !k11->provider->valid) {
|
||||
+ error("no pkcs11 (valid) provider for ecdsa %p", ecdsa);
|
||||
+ return NULL;
|
||||
+ }
|
||||
+ f = k11->provider->function_list;
|
||||
+ si = &k11->provider->slotinfo[k11->slotidx];
|
||||
+ if(pkcs11_login(k11, f, si)) {
|
||||
+ return NULL;
|
||||
+ }
|
||||
+ key_filter[1].pValue = k11->keyid;
|
||||
+ key_filter[1].ulValueLen = k11->keyid_len;
|
||||
+ /* try to find object w/CKA_SIGN first, retry w/o */
|
||||
+ if (pkcs11_find(k11->provider, k11->slotidx, key_filter, 3, &obj) < 0 &&
|
||||
+ pkcs11_find(k11->provider, k11->slotidx, key_filter, 2, &obj) < 0) {
|
||||
+ error("cannot find private key");
|
||||
+ } else if ((rv = f->C_SignInit(si->session, &mech, obj)) != CKR_OK) {
|
||||
+ error("C_SignInit failed: %lu", rv);
|
||||
+ } else {
|
||||
+ CK_BYTE_PTR buf = NULL;
|
||||
+ BIGNUM *r = NULL, *s = NULL;
|
||||
+ int nlen;
|
||||
+ /* Make a call to C_Sign to find out the size of the signature */
|
||||
+ rv = f->C_Sign(si->session, (CK_BYTE *)dgst, dgst_len, NULL, &tlen);
|
||||
+ if (rv != CKR_OK) {
|
||||
+ error("C_Sign failed: %lu", rv);
|
||||
+ return NULL;
|
||||
+ }
|
||||
+ if ((buf = xmalloc(tlen)) == NULL) {
|
||||
+ error("failure to allocate signature buffer");
|
||||
+ return NULL;
|
||||
+ }
|
||||
+ rv = f->C_Sign(si->session, (CK_BYTE *)dgst, dgst_len, buf, &tlen);
|
||||
+ if (rv != CKR_OK) {
|
||||
+ error("C_Sign failed: %lu", rv);
|
||||
+ }
|
||||
+
|
||||
+ if ((rval = ECDSA_SIG_new()) == NULL ||
|
||||
+ (r = BN_new()) == NULL ||
|
||||
+ (s = BN_new()) == NULL) {
|
||||
+ error("failure to allocate ECDSA signature");
|
||||
+ } else {
|
||||
+ /*
|
||||
+ * ECDSA signature is 2 large integers of same size returned
|
||||
+ * concatenated by PKCS#11, we separate them to create an
|
||||
+ * ECDSA_SIG for OpenSSL.
|
||||
+ */
|
||||
+ nlen = tlen / 2;
|
||||
+ BN_bin2bn(&buf[0], nlen, r);
|
||||
+ BN_bin2bn(&buf[nlen], nlen, s);
|
||||
+ ECDSA_SIG_set0(rval, r, s);
|
||||
+ }
|
||||
+ free(buf);
|
||||
+ }
|
||||
+ return (rval);
|
||||
+}
|
||||
+
|
||||
+#if (OPENSSL_VERSION_NUMBER >= 0x00010100L)
|
||||
+static EC_KEY_METHOD *get_pkcs11_ecdsa_method(void) {
|
||||
+ static EC_KEY_METHOD *pkcs11_ecdsa_method = NULL;
|
||||
+ if(pkcs11_key_idx == -1) {
|
||||
+ pkcs11_key_idx = EC_KEY_get_ex_new_index(0, NULL, NULL, NULL, 0);
|
||||
+ }
|
||||
+ if (pkcs11_ecdsa_method == NULL) {
|
||||
+ const EC_KEY_METHOD *def = EC_KEY_get_default_method();
|
||||
+ pkcs11_ecdsa_method = EC_KEY_METHOD_new(def);
|
||||
+ EC_KEY_METHOD_set_sign(pkcs11_ecdsa_method, NULL, NULL, pkcs11_ecdsa_sign);
|
||||
+ }
|
||||
+#else
|
||||
+static ECDSA_METHOD *get_pkcs11_ecdsa_method(void) {
|
||||
+ static ECDSA_METHOD *pkcs11_ecdsa_method = NULL;
|
||||
+ if(pkcs11_key_idx == -1) {
|
||||
+ pkcs11_key_idx = ECDSA_get_ex_new_index(0, NULL, NULL, NULL, 0);
|
||||
+ }
|
||||
+ if(pkcs11_ecdsa_method == NULL) {
|
||||
+ const ECDSA_METHOD *def = ECDSA_get_default_method();
|
||||
+ #ifdef ECDSA_F_ECDSA_METHOD_NEW
|
||||
+ pkcs11_ecdsa_method = ECDSA_METHOD_new((ECDSA_METHOD *)def);
|
||||
+ ECDSA_METHOD_set_name(pkcs11_ecdsa_method, "pkcs11");
|
||||
+ ECDSA_METHOD_set_sign(pkcs11_ecdsa_method, pkcs11_ecdsa_sign);
|
||||
+ #else
|
||||
+ pkcs11_ecdsa_method = xcalloc(1, sizeof(*pkcs11_ecdsa_method));
|
||||
+ memcpy(pkcs11_ecdsa_method, def, sizeof(*pkcs11_ecdsa_method));
|
||||
+ pkcs11_ecdsa_method->name = "pkcs11";
|
||||
+ pkcs11_ecdsa_method->ecdsa_do_sign = pkcs11_ecdsa_sign;
|
||||
+ #endif
|
||||
+ }
|
||||
+#endif
|
||||
+ return pkcs11_ecdsa_method;
|
||||
+}
|
||||
+
|
||||
+static int
|
||||
+pkcs11_ecdsa_wrap(struct pkcs11_provider *provider, CK_ULONG slotidx,
|
||||
+ CK_ATTRIBUTE *keyid_attrib, CK_ATTRIBUTE *label_attrib, EC_KEY *ecdsa)
|
||||
+{
|
||||
+ struct pkcs11_key *k11;
|
||||
+ k11 = xcalloc(1, sizeof(*k11));
|
||||
+ k11->key_type = CKK_EC;
|
||||
+ k11->provider = provider;
|
||||
+ provider->refcount++; /* provider referenced by ECDSA key */
|
||||
+ k11->slotidx = slotidx;
|
||||
+ /* identify key object on smartcard */
|
||||
+ k11->keyid_len = keyid_attrib->ulValueLen;
|
||||
+ if (k11->keyid_len > 0) {
|
||||
+ k11->keyid = xmalloc(k11->keyid_len);
|
||||
+ memcpy(k11->keyid, keyid_attrib->pValue, k11->keyid_len);
|
||||
+ }
|
||||
+ if (label_attrib->ulValueLen > 0 ) {
|
||||
+ k11->label = xmalloc(label_attrib->ulValueLen+1);
|
||||
+ memcpy(k11->label, label_attrib->pValue, label_attrib->ulValueLen);
|
||||
+ k11->label[label_attrib->ulValueLen] = 0;
|
||||
+ }
|
||||
+ #if (OPENSSL_VERSION_NUMBER >= 0x00010100L)
|
||||
+ EC_KEY_set_method(ecdsa, get_pkcs11_ecdsa_method());
|
||||
+ EC_KEY_set_ex_data(ecdsa, pkcs11_key_idx, k11);
|
||||
+ #else
|
||||
+ ECDSA_set_method(ecdsa, get_pkcs11_ecdsa_method());
|
||||
+ ECDSA_set_ex_data(ecdsa, pkcs11_key_idx, k11);
|
||||
+ #endif
|
||||
+ return (0);
|
||||
+}
|
||||
+#endif /* ENABLE_PKCS11_ECDSA */
|
||||
+
|
||||
+int pkcs11_del_key(struct sshkey *key) {
|
||||
+#ifdef ENABLE_PKCS11_ECDSA
|
||||
+ if(key->type == KEY_ECDSA) {
|
||||
+ struct pkcs11_key *k11 = (struct pkcs11_key *)
|
||||
+ #if (OPENSSL_VERSION_NUMBER >= 0x00010100L)
|
||||
+ EC_KEY_get_ex_data(key->ecdsa, pkcs11_key_idx);
|
||||
+ #else
|
||||
+ ECDSA_get_ex_data(key->ecdsa, pkcs11_key_idx);
|
||||
+ #endif
|
||||
+ if (k11 == NULL) {
|
||||
+ error("EC_KEY_get_ex_data failed for ecdsa %p", key->ecdsa);
|
||||
+ } else {
|
||||
+ if (k11->provider)
|
||||
+ pkcs11_provider_unref(k11->provider);
|
||||
+ free(k11->keyid);
|
||||
+ free(k11);
|
||||
+ }
|
||||
+ }
|
||||
+#endif /* ENABLE_PKCS11_ECDSA */
|
||||
+ sshkey_free(key);
|
||||
+ return (0);
|
||||
+}
|
||||
+
|
||||
/* remove trailing spaces */
|
||||
static void
|
||||
rmspace(u_char *buf, size_t len)
|
||||
@@ -482,11 +646,13 @@ static int
|
||||
pkcs11_fetch_keys(struct pkcs11_provider *p, CK_ULONG slotidx,
|
||||
struct sshkey ***keysp, int *nkeys, struct pkcs11_uri *uri)
|
||||
{
|
||||
- size_t filter_size = 1;
|
||||
+ size_t filter_size = 2;
|
||||
+ CK_KEY_TYPE pubkey_type = CKK_RSA;
|
||||
CK_OBJECT_CLASS pubkey_class = CKO_PUBLIC_KEY;
|
||||
CK_OBJECT_CLASS cert_class = CKO_CERTIFICATE;
|
||||
CK_ATTRIBUTE pubkey_filter[] = {
|
||||
{ CKA_CLASS, NULL, sizeof(pubkey_class) },
|
||||
+ { CKA_KEY_TYPE, NULL, sizeof(pubkey_type) },
|
||||
{ CKA_ID, NULL, 0 },
|
||||
{ CKA_LABEL, NULL, 0 }
|
||||
};
|
||||
@@ -507,29 +673,60 @@ pkcs11_fetch_keys(struct pkcs11_provider
|
||||
{ CKA_SUBJECT, NULL, 0 },
|
||||
{ CKA_VALUE, NULL, 0 }
|
||||
};
|
||||
+#ifdef ENABLE_PKCS11_ECDSA
|
||||
+ CK_KEY_TYPE ecdsa_type = CKK_EC;
|
||||
+ CK_ATTRIBUTE ecdsa_filter[] = {
|
||||
+ { CKA_CLASS, NULL, sizeof(pubkey_class) },
|
||||
+ { CKA_KEY_TYPE, NULL, sizeof(ecdsa_type) },
|
||||
+ { CKA_ID, NULL, 0 },
|
||||
+ { CKA_LABEL, NULL, 0 }
|
||||
+ };
|
||||
+ CK_ATTRIBUTE ecdsa_attribs[] = {
|
||||
+ { CKA_ID, NULL, 0 },
|
||||
+ { CKA_LABEL, NULL, 0 },
|
||||
+ { CKA_EC_PARAMS, NULL, 0 },
|
||||
+ { CKA_EC_POINT, NULL, 0 }
|
||||
+ };
|
||||
+ ecdsa_filter[0].pValue = &pubkey_class;
|
||||
+ ecdsa_filter[1].pValue = &ecdsa_type;
|
||||
+#endif /* ENABLE_PKCS11_ECDSA */
|
||||
pubkey_filter[0].pValue = &pubkey_class;
|
||||
+ pubkey_filter[1].pValue = &pubkey_type;
|
||||
cert_filter[0].pValue = &cert_class;
|
||||
|
||||
if (uri->id != NULL) {
|
||||
pubkey_filter[filter_size].pValue = uri->id;
|
||||
pubkey_filter[filter_size].ulValueLen = uri->id_len;
|
||||
- cert_filter[filter_size].pValue = uri->id;
|
||||
- cert_filter[filter_size].ulValueLen = uri->id_len;
|
||||
+#ifdef ENABLE_PKCS11_ECDSA
|
||||
+ ecdsa_filter[filter_size].pValue = uri->id;
|
||||
+ ecdsa_filter[filter_size].ulValueLen = uri->id_len;
|
||||
+#endif /* ENABLE_PKCS11_ECDSA */
|
||||
+ cert_filter[filter_size-1].pValue = uri->id;
|
||||
+ cert_filter[filter_size-1].ulValueLen = uri->id_len;
|
||||
filter_size++;
|
||||
}
|
||||
if (uri->object != NULL) {
|
||||
pubkey_filter[filter_size].pValue = uri->object;
|
||||
pubkey_filter[filter_size].ulValueLen = strlen(uri->object);
|
||||
pubkey_filter[filter_size].type = CKA_LABEL;
|
||||
- cert_filter[filter_size].pValue = uri->object;
|
||||
- cert_filter[filter_size].ulValueLen = strlen(uri->object);
|
||||
- cert_filter[filter_size].type = CKA_LABEL;
|
||||
+#ifdef ENABLE_PKCS11_ECDSA
|
||||
+ ecdsa_filter[filter_size].pValue = uri->object;
|
||||
+ ecdsa_filter[filter_size].ulValueLen = strlen(uri->object);
|
||||
+ ecdsa_filter[filter_size].type = CKA_LABEL;
|
||||
+#endif /* ENABLE_PKCS11_ECDSA */
|
||||
+ cert_filter[filter_size-1].pValue = uri->object;
|
||||
+ cert_filter[filter_size-1].ulValueLen = strlen(uri->object);
|
||||
+ cert_filter[filter_size-1].type = CKA_LABEL;
|
||||
filter_size++;
|
||||
}
|
||||
|
||||
if (pkcs11_fetch_keys_filter(p, slotidx, pubkey_filter, filter_size,
|
||||
pubkey_attribs, keysp, nkeys) < 0 ||
|
||||
- pkcs11_fetch_keys_filter(p, slotidx, cert_filter, filter_size,
|
||||
+#ifdef ENABLE_PKCS11_ECDSA
|
||||
+ pkcs11_fetch_keys_filter(p, slotidx, ecdsa_filter, filter_size,
|
||||
+ ecdsa_attribs, keysp, nkeys) < 0||
|
||||
+#endif /* ENABLE_PKCS11_ECDSA */
|
||||
+ pkcs11_fetch_keys_filter(p, slotidx, cert_filter, filter_size - 1,
|
||||
cert_attribs, keysp, nkeys) < 0)
|
||||
return (-1);
|
||||
return (0);
|
||||
@@ -553,6 +746,11 @@ pkcs11_fetch_keys_filter(struct pkcs11_p
|
||||
{
|
||||
struct sshkey *key;
|
||||
RSA *rsa;
|
||||
+#ifdef ENABLE_PKCS11_ECDSA
|
||||
+ EC_KEY *ecdsa;
|
||||
+#else
|
||||
+ void *ecdsa;
|
||||
+#endif /* ENABLE_PKCS11_ECDSA */
|
||||
X509 *x509;
|
||||
EVP_PKEY *evp = NULL;
|
||||
int i;
|
||||
@@ -608,6 +806,9 @@ pkcs11_fetch_keys_filter(struct pkcs11_p
|
||||
* or ID, label, subject and value for certificates.
|
||||
*/
|
||||
rsa = NULL;
|
||||
+#ifdef ENABLE_PKCS11_ECDSA
|
||||
+ ecdsa = NULL;
|
||||
+#endif /* ENABLE_PKCS11_ECDSA */
|
||||
if ((rv = f->C_GetAttributeValue(session, obj, attribs, nattribs))
|
||||
!= CKR_OK) {
|
||||
error("C_GetAttributeValue failed: %lu", rv);
|
||||
@@ -620,6 +821,45 @@ pkcs11_fetch_keys_filter(struct pkcs11_p
|
||||
rsa->e = BN_bin2bn(attribs[3].pValue,
|
||||
attribs[3].ulValueLen, NULL);
|
||||
}
|
||||
+#ifdef ENABLE_PKCS11_ECDSA
|
||||
+ } else if (attribs[2].type == CKA_EC_PARAMS ) {
|
||||
+ if ((ecdsa = EC_KEY_new()) == NULL) {
|
||||
+ error("EC_KEY_new failed");
|
||||
+ } else {
|
||||
+ const unsigned char *ptr1 = attribs[2].pValue;
|
||||
+ const unsigned char *ptr2 = attribs[3].pValue;
|
||||
+ CK_ULONG len1 = attribs[2].ulValueLen;
|
||||
+ CK_ULONG len2 = attribs[3].ulValueLen;
|
||||
+ ASN1_OCTET_STRING *point = NULL;
|
||||
+
|
||||
+ /*
|
||||
+ * CKA_EC_PARAMS contains the curve parameters of the key
|
||||
+ * either referenced as an OID or directly with all values.
|
||||
+ * CKA_EC_POINT contains the point (public key) on the curve.
|
||||
+ * The point is should be returned inside a DER-encoded
|
||||
+ * ASN.1 OCTET STRING value (but some implementation).
|
||||
+ */
|
||||
+ if ((point = d2i_ASN1_OCTET_STRING(NULL, &ptr2, len2))) {
|
||||
+ /* Pointing to OCTET STRING content */
|
||||
+ ptr2 = point->data;
|
||||
+ len2 = point->length;
|
||||
+ } else {
|
||||
+ /* No OCTET STRING */
|
||||
+ ptr2 = attribs[3].pValue;
|
||||
+ }
|
||||
+
|
||||
+ if((d2i_ECParameters(&ecdsa, &ptr1, len1) == NULL) ||
|
||||
+ (o2i_ECPublicKey(&ecdsa, &ptr2, len2) == NULL)) {
|
||||
+ EC_KEY_free(ecdsa);
|
||||
+ ecdsa = NULL;
|
||||
+ error("EC public key parsing failed");
|
||||
+ }
|
||||
+
|
||||
+ if(point) {
|
||||
+ ASN1_OCTET_STRING_free(point);
|
||||
+ }
|
||||
+ }
|
||||
+#endif /* ENABLE_PKCS11_ECDSA */
|
||||
} else {
|
||||
cp = attribs[3].pValue;
|
||||
if ((x509 = X509_new()) == NULL) {
|
||||
@@ -639,13 +879,28 @@ pkcs11_fetch_keys_filter(struct pkcs11_p
|
||||
X509_free(x509);
|
||||
EVP_PKEY_free(evp);
|
||||
}
|
||||
- if (rsa && rsa->n && rsa->e &&
|
||||
- pkcs11_rsa_wrap(p, slotidx, &attribs[0], &attribs[1], rsa) == 0) {
|
||||
- if ((key = sshkey_new(KEY_UNSPEC)) == NULL)
|
||||
- fatal("sshkey_new failed");
|
||||
- key->rsa = rsa;
|
||||
- key->type = KEY_RSA;
|
||||
- key->flags |= SSHKEY_FLAG_EXT;
|
||||
+ key = NULL;
|
||||
+ if (rsa || ecdsa) {
|
||||
+ if (rsa && rsa->n && rsa->e &&
|
||||
+ pkcs11_rsa_wrap(p, slotidx, &attribs[0], &attribs[1], rsa) == 0) {
|
||||
+ if ((key = sshkey_new(KEY_UNSPEC)) == NULL)
|
||||
+ fatal("sshkey_new failed");
|
||||
+ key->rsa = rsa;
|
||||
+ key->type = KEY_RSA;
|
||||
+ key->flags |= SSHKEY_FLAG_EXT;
|
||||
+#ifdef ENABLE_PKCS11_ECDSA
|
||||
+ } else if(ecdsa && pkcs11_ecdsa_wrap(p, slotidx, &attribs[0], &attribs[1], ecdsa) == 0) {
|
||||
+ if ((key = sshkey_new(KEY_UNSPEC)) == NULL)
|
||||
+ fatal("sshkey_new failed");
|
||||
+ key->ecdsa = ecdsa;
|
||||
+ key->ecdsa_nid = sshkey_ecdsa_key_to_nid(ecdsa);
|
||||
+ key->type = KEY_ECDSA;
|
||||
+ key->flags |= SSHKEY_FLAG_EXT;
|
||||
+#endif /* ENABLE_PKCS11_ECDSA */
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ if(key) {
|
||||
if (pkcs11_key_included(keysp, nkeys, key)) {
|
||||
sshkey_free(key);
|
||||
} else {
|
||||
@@ -658,6 +913,10 @@ pkcs11_fetch_keys_filter(struct pkcs11_p
|
||||
}
|
||||
} else if (rsa) {
|
||||
RSA_free(rsa);
|
||||
+#ifdef ENABLE_PKCS11_ECDSA
|
||||
+ } else if (ecdsa) {
|
||||
+ EC_KEY_free(ecdsa);
|
||||
+#endif /* ENABLE_PKCS11_ECDSA */
|
||||
}
|
||||
for (i = 0; i < nattribs; i++)
|
||||
free(attribs[i].pValue);
|
||||
diff -up openssh-7.6p1/ssh-pkcs11-helper.c.pkcs11-ecdsa openssh-7.6p1/ssh-pkcs11-helper.c
|
||||
--- openssh-7.6p1/ssh-pkcs11-helper.c.pkcs11-ecdsa 2017-10-02 21:34:26.000000000 +0200
|
||||
+++ openssh-7.6p1/ssh-pkcs11-helper.c 2018-02-16 13:25:59.428469265 +0100
|
||||
@@ -24,6 +24,17 @@
|
||||
|
||||
#include "openbsd-compat/sys-queue.h"
|
||||
|
||||
+#include <openssl/rsa.h>
|
||||
+#ifdef OPENSSL_HAS_ECC
|
||||
+#include <openssl/ecdsa.h>
|
||||
+#if ((defined(LIBRESSL_VERSION_NUMBER) && \
|
||||
+ (LIBRESSL_VERSION_NUMBER >= 0x20010002L))) || \
|
||||
+ (defined(ECDSA_F_ECDSA_METHOD_NEW)) || \
|
||||
+ (OPENSSL_VERSION_NUMBER >= 0x00010100L)
|
||||
+#define ENABLE_PKCS11_ECDSA 1
|
||||
+#endif
|
||||
+#endif
|
||||
+
|
||||
#include <stdarg.h>
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
@@ -80,7 +90,7 @@ del_keys_by_name(char *name)
|
||||
if (!strcmp(ki->providername, name)) {
|
||||
TAILQ_REMOVE(&pkcs11_keylist, ki, next);
|
||||
free(ki->providername);
|
||||
- key_free(ki->key);
|
||||
+ pkcs11_del_key(ki->key);
|
||||
free(ki);
|
||||
}
|
||||
}
|
||||
@@ -164,6 +174,20 @@ process_del(void)
|
||||
buffer_free(&msg);
|
||||
}
|
||||
|
||||
+#ifdef ENABLE_PKCS11_ECDSA
|
||||
+static u_int EC_KEY_order_size(EC_KEY *key)
|
||||
+{
|
||||
+ const EC_GROUP *group = EC_KEY_get0_group(key);
|
||||
+ BIGNUM *order = BN_new();
|
||||
+ u_int nbytes = 0;
|
||||
+ if ((group != NULL) && (order != NULL) && EC_GROUP_get_order(group, order, NULL)) {
|
||||
+ nbytes = BN_num_bytes(order);
|
||||
+ }
|
||||
+ BN_clear_free(order);
|
||||
+ return nbytes;
|
||||
+}
|
||||
+#endif /* ENABLE_PKCS11_ECDSA */
|
||||
+
|
||||
static void
|
||||
process_sign(void)
|
||||
{
|
||||
@@ -180,14 +204,38 @@ process_sign(void)
|
||||
if ((key = key_from_blob(blob, blen)) != NULL) {
|
||||
if ((found = lookup_key(key)) != NULL) {
|
||||
#ifdef WITH_OPENSSL
|
||||
- int ret;
|
||||
-
|
||||
- slen = RSA_size(key->rsa);
|
||||
- signature = xmalloc(slen);
|
||||
- if ((ret = RSA_private_encrypt(dlen, data, signature,
|
||||
- found->rsa, RSA_PKCS1_PADDING)) != -1) {
|
||||
- slen = ret;
|
||||
- ok = 0;
|
||||
+ if(found->type == KEY_RSA) {
|
||||
+ int ret;
|
||||
+ slen = RSA_size(key->rsa);
|
||||
+ signature = xmalloc(slen);
|
||||
+ if ((ret = RSA_private_encrypt(dlen, data, signature,
|
||||
+ found->rsa, RSA_PKCS1_PADDING)) != -1) {
|
||||
+ slen = ret;
|
||||
+ ok = 0;
|
||||
+ }
|
||||
+#ifdef ENABLE_PKCS11_ECDSA
|
||||
+ } else if(found->type == KEY_ECDSA) {
|
||||
+ ECDSA_SIG *sig;
|
||||
+ const BIGNUM *r = NULL, *s = NULL;
|
||||
+ if ((sig = ECDSA_do_sign(data, dlen, found->ecdsa)) != NULL) {
|
||||
+ /* PKCS11 2.3.1 recommends both r and s to have the order size for
|
||||
+ backward compatiblity */
|
||||
+ ECDSA_SIG_get0(sig, &r, &s);
|
||||
+ u_int o_len = EC_KEY_order_size(found->ecdsa);
|
||||
+ u_int r_len = BN_num_bytes(r);
|
||||
+ u_int s_len = BN_num_bytes(s);
|
||||
+ if (o_len > 0 && r_len <= o_len && s_len <= o_len) {
|
||||
+ signature = xcalloc(2, o_len);
|
||||
+ BN_bn2bin(r, signature + o_len - r_len);
|
||||
+ BN_bn2bin(s, signature + (2 * o_len) - s_len);
|
||||
+ slen = 2 * o_len;
|
||||
+ ok = 0;
|
||||
+ }
|
||||
+ ECDSA_SIG_free(sig);
|
||||
+ }
|
||||
+#endif /* ENABLE_PKCS11_ECDSA */
|
||||
+ } else {
|
||||
+ /* Unsupported type */
|
||||
}
|
||||
#endif /* WITH_OPENSSL */
|
||||
}
|
||||
diff -up openssh-7.6p1/ssh-pkcs11.h.pkcs11-ecdsa openssh-7.6p1/ssh-pkcs11.h
|
||||
--- openssh-7.6p1/ssh-pkcs11.h.pkcs11-ecdsa 2018-02-16 13:25:59.429469272 +0100
|
||||
+++ openssh-7.6p1/ssh-pkcs11.h 2018-02-16 13:45:29.623800048 +0100
|
||||
@@ -20,6 +20,7 @@
|
||||
int pkcs11_init(int);
|
||||
void pkcs11_terminate(void);
|
||||
int pkcs11_add_provider(char *, char *, struct sshkey ***);
|
||||
+int pkcs11_del_key(struct sshkey *);
|
||||
int pkcs11_add_provider_by_uri(struct pkcs11_uri *, char *, struct sshkey ***);
|
||||
int pkcs11_del_provider(char *);
|
||||
int pkcs11_uri_write(const struct sshkey *, FILE *);
|
4464
openssh-7.6p1-pkcs11-uri.patch
Normal file
4464
openssh-7.6p1-pkcs11-uri.patch
Normal file
File diff suppressed because it is too large
Load Diff
@ -226,6 +226,10 @@ Patch948: openssh-7.4p1-systemd.patch
|
||||
Patch949: openssh-7.6p1-cleanup-selinux.patch
|
||||
# Sandbox adjustments for s390 and audit
|
||||
Patch950: openssh-7.5p1-sandbox.patch
|
||||
# PKCS#11 URIs (upstream #2817, 2nd iteration)
|
||||
Patch951: openssh-7.6p1-pkcs11-uri.patch
|
||||
# PKCS#11 ECDSA keys (upstream #2474, 8th iteration)
|
||||
Patch952: openssh-7.6p1-pkcs11-ecdsa.patch
|
||||
|
||||
|
||||
License: BSD
|
||||
@ -449,6 +453,8 @@ popd
|
||||
%patch807 -p1 -b .gsskex-ec
|
||||
%patch949 -p1 -b .refactor
|
||||
%patch950 -p1 -b .sandbox
|
||||
%patch951 -p1 -b .pkcs11-uri
|
||||
%patch952 -p1 -b .pkcs11-ecdsa
|
||||
|
||||
%patch200 -p1 -b .audit
|
||||
%patch201 -p1 -b .audit-race
|
||||
|
Loading…
Reference in New Issue
Block a user