|
|
71e593 |
From 3906e5f41a00063127e07f5ca696a25eea2e8bb7 Mon Sep 17 00:00:00 2001
|
|
|
71e593 |
From: Sumit Bose <sbose@redhat.com>
|
|
|
71e593 |
Date: Fri, 16 Nov 2018 18:15:32 +0100
|
|
|
71e593 |
Subject: [PATCH 74/74] utils: add ec_pub_key_to_ssh() (NSS)
|
|
|
71e593 |
|
|
|
71e593 |
Add EC key support for the NSS version of the ssh key extraction code.
|
|
|
71e593 |
|
|
|
71e593 |
Related to https://pagure.io/SSSD/sssd/issue/3887
|
|
|
71e593 |
|
|
|
71e593 |
Reviewed-by: Jakub Hrozek <jhrozek@redhat.com>
|
|
|
71e593 |
---
|
|
|
71e593 |
src/util/cert/nss/cert.c | 121 ++++++++++++++++++++++++++++++++++++++-
|
|
|
71e593 |
1 file changed, 120 insertions(+), 1 deletion(-)
|
|
|
71e593 |
|
|
|
71e593 |
diff --git a/src/util/cert/nss/cert.c b/src/util/cert/nss/cert.c
|
|
|
71e593 |
index b5c4769a8..ad90da0da 100644
|
|
|
71e593 |
--- a/src/util/cert/nss/cert.c
|
|
|
71e593 |
+++ b/src/util/cert/nss/cert.c
|
|
|
71e593 |
@@ -220,6 +220,118 @@ done:
|
|
|
71e593 |
return ret;
|
|
|
71e593 |
}
|
|
|
71e593 |
|
|
|
71e593 |
+/* taken from NSS's lib/cryptohi/seckey.c */
|
|
|
71e593 |
+static SECOidTag
|
|
|
71e593 |
+sss_SECKEY_GetECCOid(const SECKEYECParams *params)
|
|
|
71e593 |
+{
|
|
|
71e593 |
+ SECItem oid = { siBuffer, NULL, 0 };
|
|
|
71e593 |
+ SECOidData *oidData = NULL;
|
|
|
71e593 |
+
|
|
|
71e593 |
+ /*
|
|
|
71e593 |
+ * params->data needs to contain the ASN encoding of an object ID (OID)
|
|
|
71e593 |
+ * representing a named curve. Here, we strip away everything
|
|
|
71e593 |
+ * before the actual OID and use the OID to look up a named curve.
|
|
|
71e593 |
+ */
|
|
|
71e593 |
+ if (params->data[0] != SEC_ASN1_OBJECT_ID)
|
|
|
71e593 |
+ return 0;
|
|
|
71e593 |
+ oid.len = params->len - 2;
|
|
|
71e593 |
+ oid.data = params->data + 2;
|
|
|
71e593 |
+ if ((oidData = SECOID_FindOID(&oid)) == NULL)
|
|
|
71e593 |
+ return 0;
|
|
|
71e593 |
+
|
|
|
71e593 |
+ return oidData->offset;
|
|
|
71e593 |
+}
|
|
|
71e593 |
+
|
|
|
71e593 |
+/* SSH EC keys are defined in https://tools.ietf.org/html/rfc5656 */
|
|
|
71e593 |
+#define ECDSA_SHA2_HEADER "ecdsa-sha2-"
|
|
|
71e593 |
+/* Looks like OpenSSH currently only supports the following 3 required
|
|
|
71e593 |
+ * curves. */
|
|
|
71e593 |
+#define IDENTIFIER_NISTP256 "nistp256"
|
|
|
71e593 |
+#define IDENTIFIER_NISTP384 "nistp384"
|
|
|
71e593 |
+#define IDENTIFIER_NISTP521 "nistp521"
|
|
|
71e593 |
+
|
|
|
71e593 |
+static errno_t ec_pub_key_to_ssh(TALLOC_CTX *mem_ctx,
|
|
|
71e593 |
+ SECKEYPublicKey *cert_pub_key,
|
|
|
71e593 |
+ uint8_t **key_blob, size_t *key_size)
|
|
|
71e593 |
+{
|
|
|
71e593 |
+ int ret;
|
|
|
71e593 |
+ size_t c;
|
|
|
71e593 |
+ uint8_t *buf = NULL;
|
|
|
71e593 |
+ size_t buf_len;
|
|
|
71e593 |
+ SECOidTag curve_tag;
|
|
|
71e593 |
+ int key_len;
|
|
|
71e593 |
+ const char *identifier = NULL;
|
|
|
71e593 |
+ int identifier_len;
|
|
|
71e593 |
+ const char *header = NULL;
|
|
|
71e593 |
+ int header_len;
|
|
|
71e593 |
+ SECItem *ec_public_key;
|
|
|
71e593 |
+
|
|
|
71e593 |
+ curve_tag = sss_SECKEY_GetECCOid(&cert_pub_key->u.ec.DEREncodedParams);
|
|
|
71e593 |
+ switch(curve_tag) {
|
|
|
71e593 |
+ case SEC_OID_ANSIX962_EC_PRIME256V1:
|
|
|
71e593 |
+ identifier = IDENTIFIER_NISTP256;
|
|
|
71e593 |
+ header = ECDSA_SHA2_HEADER IDENTIFIER_NISTP256;
|
|
|
71e593 |
+ break;
|
|
|
71e593 |
+ case SEC_OID_SECG_EC_SECP384R1:
|
|
|
71e593 |
+ identifier = IDENTIFIER_NISTP384;
|
|
|
71e593 |
+ header = ECDSA_SHA2_HEADER IDENTIFIER_NISTP384;
|
|
|
71e593 |
+ break;
|
|
|
71e593 |
+ case SEC_OID_SECG_EC_SECP521R1:
|
|
|
71e593 |
+ identifier = IDENTIFIER_NISTP521;
|
|
|
71e593 |
+ header = ECDSA_SHA2_HEADER IDENTIFIER_NISTP521;
|
|
|
71e593 |
+ break;
|
|
|
71e593 |
+ default:
|
|
|
71e593 |
+ DEBUG(SSSDBG_CRIT_FAILURE, "Unsupported curve [%s]\n",
|
|
|
71e593 |
+ SECOID_FindOIDTagDescription(curve_tag));
|
|
|
71e593 |
+ ret = EINVAL;
|
|
|
71e593 |
+ goto done;
|
|
|
71e593 |
+ }
|
|
|
71e593 |
+
|
|
|
71e593 |
+ header_len = strlen(header);
|
|
|
71e593 |
+ identifier_len = strlen(identifier);
|
|
|
71e593 |
+
|
|
|
71e593 |
+ ec_public_key = &cert_pub_key->u.ec.publicValue;
|
|
|
71e593 |
+
|
|
|
71e593 |
+ key_len = ec_public_key->len;
|
|
|
71e593 |
+ if (key_len == 0) {
|
|
|
71e593 |
+ DEBUG(SSSDBG_OP_FAILURE, "EC_POINT_point2oct failed.\n");
|
|
|
71e593 |
+ ret = EINVAL;
|
|
|
71e593 |
+ goto done;
|
|
|
71e593 |
+ }
|
|
|
71e593 |
+
|
|
|
71e593 |
+ buf_len = header_len + identifier_len + key_len + 3 * sizeof(uint32_t);
|
|
|
71e593 |
+ buf = talloc_size(mem_ctx, buf_len * sizeof(uint8_t));
|
|
|
71e593 |
+ if (buf == NULL) {
|
|
|
71e593 |
+ DEBUG(SSSDBG_OP_FAILURE, "talloc_size failed.\n");
|
|
|
71e593 |
+ ret = ENOMEM;
|
|
|
71e593 |
+ goto done;
|
|
|
71e593 |
+ }
|
|
|
71e593 |
+
|
|
|
71e593 |
+ c = 0;
|
|
|
71e593 |
+
|
|
|
71e593 |
+ SAFEALIGN_SET_UINT32(buf, htobe32(header_len), &c);
|
|
|
71e593 |
+ safealign_memcpy(&buf[c], header, header_len, &c);
|
|
|
71e593 |
+
|
|
|
71e593 |
+ SAFEALIGN_SET_UINT32(&buf[c], htobe32(identifier_len), &c);
|
|
|
71e593 |
+ safealign_memcpy(&buf[c], identifier , identifier_len, &c);
|
|
|
71e593 |
+
|
|
|
71e593 |
+ SAFEALIGN_SET_UINT32(&buf[c], htobe32(key_len), &c);
|
|
|
71e593 |
+
|
|
|
71e593 |
+ safealign_memcpy(&buf[c], ec_public_key->data, key_len, &c);
|
|
|
71e593 |
+
|
|
|
71e593 |
+ *key_size = buf_len;
|
|
|
71e593 |
+ *key_blob = buf;
|
|
|
71e593 |
+
|
|
|
71e593 |
+ ret = EOK;
|
|
|
71e593 |
+
|
|
|
71e593 |
+done:
|
|
|
71e593 |
+ if (ret != EOK) {
|
|
|
71e593 |
+ talloc_free(buf);
|
|
|
71e593 |
+ }
|
|
|
71e593 |
+
|
|
|
71e593 |
+ return ret;
|
|
|
71e593 |
+}
|
|
|
71e593 |
+
|
|
|
71e593 |
#define SSH_RSA_HEADER "ssh-rsa"
|
|
|
71e593 |
#define SSH_RSA_HEADER_LEN (sizeof(SSH_RSA_HEADER) - 1)
|
|
|
71e593 |
|
|
|
71e593 |
@@ -340,9 +452,16 @@ errno_t get_ssh_key_from_cert(TALLOC_CTX *mem_ctx,
|
|
|
71e593 |
goto done;
|
|
|
71e593 |
}
|
|
|
71e593 |
break;
|
|
|
71e593 |
+ case ecKey:
|
|
|
71e593 |
+ ret = ec_pub_key_to_ssh(mem_ctx, cert_pub_key, key_blob, key_size);
|
|
|
71e593 |
+ if (ret != EOK) {
|
|
|
71e593 |
+ DEBUG(SSSDBG_OP_FAILURE, "rsa_pub_key_to_ssh failed.\n");
|
|
|
71e593 |
+ goto done;
|
|
|
71e593 |
+ }
|
|
|
71e593 |
+ break;
|
|
|
71e593 |
default:
|
|
|
71e593 |
DEBUG(SSSDBG_CRIT_FAILURE,
|
|
|
71e593 |
- "Expected RSA public key, found unsupported [%d].\n",
|
|
|
71e593 |
+ "Expected RSA or EC public key, found unsupported [%d].\n",
|
|
|
71e593 |
cert_pub_key->keyType);
|
|
|
71e593 |
ret = EINVAL;
|
|
|
71e593 |
goto done;
|
|
|
71e593 |
--
|
|
|
71e593 |
2.19.1
|
|
|
71e593 |
|