Merge commit 'efad5b281a7417cf012e80915b3e8d16f05b23a7' into kazuho/cert-ed25519
diff --git a/include/picotls.h b/include/picotls.h
index 6134467..a3050c1 100644
--- a/include/picotls.h
+++ b/include/picotls.h
@@ -124,6 +124,7 @@
#define PTLS_SIGNATURE_RSA_PSS_RSAE_SHA256 0x0804
#define PTLS_SIGNATURE_RSA_PSS_RSAE_SHA384 0x0805
#define PTLS_SIGNATURE_RSA_PSS_RSAE_SHA512 0x0806
+#define PTLS_SIGNATURE_ED25519 0x0807
/* ESNI */
#define PTLS_ESNI_VERSION_DRAFT03 0xff02
diff --git a/lib/openssl.c b/lib/openssl.c
index 36344a9..4c5eaf0 100644
--- a/lib/openssl.c
+++ b/lib/openssl.c
@@ -102,6 +102,9 @@
static const struct st_ptls_openssl_signature_scheme_t secp521r1_signature_schemes[] = {
{PTLS_SIGNATURE_ECDSA_SECP521R1_SHA512, EVP_sha512}, {UINT16_MAX, NULL}};
#endif
+#if defined EVP_PKEY_ED25519
+static const struct st_ptls_openssl_signature_scheme_t ed25519_signature_schemes[] = {{PTLS_SIGNATURE_ED25519, NULL}, {UINT16_MAX, NULL}};
+#endif
/**
* The default list sent in ClientHello.signature_algorithms. ECDSA certificates are preferred.
@@ -145,6 +148,11 @@
}
EC_KEY_free(eckey);
} break;
+#if defined EVP_PKEY_ED25519
+ case EVP_PKEY_ED25519:
+ schemes = ed25519_signature_schemes;
+ break;
+#endif
default:
break;
}
@@ -688,38 +696,61 @@
ret = PTLS_ERROR_NO_MEMORY;
goto Exit;
}
+
if (EVP_DigestSignInit(ctx, &pkey_ctx, md, NULL, key) != 1) {
ret = PTLS_ERROR_LIBRARY;
goto Exit;
}
- if (EVP_PKEY_id(key) == EVP_PKEY_RSA) {
- if (EVP_PKEY_CTX_set_rsa_padding(pkey_ctx, RSA_PKCS1_PSS_PADDING) != 1) {
+
+#if defined EVP_PKEY_ED25519
+ if (EVP_PKEY_id(key) == EVP_PKEY_ED25519)
+ {
+ if (EVP_DigestSign(ctx, NULL, &siglen, input.base, input.len) != 1) {
ret = PTLS_ERROR_LIBRARY;
goto Exit;
}
- if (EVP_PKEY_CTX_set_rsa_pss_saltlen(pkey_ctx, -1) != 1) {
- ret = PTLS_ERROR_LIBRARY;
+
+ if ((ret = ptls_buffer_reserve(outbuf, siglen)) != 0)
goto Exit;
- }
- if (EVP_PKEY_CTX_set_rsa_mgf1_md(pkey_ctx, md) != 1) {
+
+ if (EVP_DigestSign(ctx, outbuf->base + outbuf->off, &siglen, input.base, input.len) != 1) {
ret = PTLS_ERROR_LIBRARY;
goto Exit;
}
}
- if (EVP_DigestSignUpdate(ctx, input.base, input.len) != 1) {
- ret = PTLS_ERROR_LIBRARY;
- goto Exit;
+ else
+#endif
+ {
+ if (EVP_PKEY_id(key) == EVP_PKEY_RSA) {
+ if (EVP_PKEY_CTX_set_rsa_padding(pkey_ctx, RSA_PKCS1_PSS_PADDING) != 1) {
+ ret = PTLS_ERROR_LIBRARY;
+ goto Exit;
+ }
+ if (EVP_PKEY_CTX_set_rsa_pss_saltlen(pkey_ctx, -1) != 1) {
+ ret = PTLS_ERROR_LIBRARY;
+ goto Exit;
+ }
+ if (EVP_PKEY_CTX_set_rsa_mgf1_md(pkey_ctx, md) != 1) {
+ ret = PTLS_ERROR_LIBRARY;
+ goto Exit;
+ }
+ }
+ if (EVP_DigestSignUpdate(ctx, input.base, input.len) != 1) {
+ ret = PTLS_ERROR_LIBRARY;
+ goto Exit;
+ }
+ if (EVP_DigestSignFinal(ctx, NULL, &siglen) != 1) {
+ ret = PTLS_ERROR_LIBRARY;
+ goto Exit;
+ }
+ if ((ret = ptls_buffer_reserve(outbuf, siglen)) != 0)
+ goto Exit;
+ if (EVP_DigestSignFinal(ctx, outbuf->base + outbuf->off, &siglen) != 1) {
+ ret = PTLS_ERROR_LIBRARY;
+ goto Exit;
+ }
}
- if (EVP_DigestSignFinal(ctx, NULL, &siglen) != 1) {
- ret = PTLS_ERROR_LIBRARY;
- goto Exit;
- }
- if ((ret = ptls_buffer_reserve(outbuf, siglen)) != 0)
- goto Exit;
- if (EVP_DigestSignFinal(ctx, outbuf->base + outbuf->off, &siglen) != 1) {
- ret = PTLS_ERROR_LIBRARY;
- goto Exit;
- }
+
outbuf->off += siglen;
ret = 0;
@@ -1054,32 +1085,52 @@
ret = PTLS_ERROR_NO_MEMORY;
goto Exit;
}
- if (EVP_DigestVerifyInit(ctx, &pkey_ctx, scheme->scheme_md(), NULL, key) != 1) {
- ret = PTLS_ERROR_LIBRARY;
- goto Exit;
- }
- if (EVP_PKEY_id(key) == EVP_PKEY_RSA) {
- if (EVP_PKEY_CTX_set_rsa_padding(pkey_ctx, RSA_PKCS1_PSS_PADDING) != 1) {
+
+#if defined EVP_PKEY_ED25519
+ if (EVP_PKEY_id(key) == EVP_PKEY_ED25519)
+ {
+ if (EVP_DigestVerifyInit(ctx, &pkey_ctx, NULL, NULL, key) != 1) {
ret = PTLS_ERROR_LIBRARY;
goto Exit;
}
- if (EVP_PKEY_CTX_set_rsa_pss_saltlen(pkey_ctx, -1) != 1) {
- ret = PTLS_ERROR_LIBRARY;
- goto Exit;
- }
- if (EVP_PKEY_CTX_set_rsa_mgf1_md(pkey_ctx, scheme->scheme_md()) != 1) {
+
+ if (EVP_DigestVerify(ctx, signature.base, signature.len, data.base, data.len) != 1) {
ret = PTLS_ERROR_LIBRARY;
goto Exit;
}
}
- if (EVP_DigestVerifyUpdate(ctx, data.base, data.len) != 1) {
- ret = PTLS_ERROR_LIBRARY;
- goto Exit;
+ else
+#endif
+ {
+ if (EVP_DigestVerifyInit(ctx, &pkey_ctx, scheme->scheme_md(), NULL, key) != 1) {
+ ret = PTLS_ERROR_LIBRARY;
+ goto Exit;
+ }
+
+ if (EVP_PKEY_id(key) == EVP_PKEY_RSA) {
+ if (EVP_PKEY_CTX_set_rsa_padding(pkey_ctx, RSA_PKCS1_PSS_PADDING) != 1) {
+ ret = PTLS_ERROR_LIBRARY;
+ goto Exit;
+ }
+ if (EVP_PKEY_CTX_set_rsa_pss_saltlen(pkey_ctx, -1) != 1) {
+ ret = PTLS_ERROR_LIBRARY;
+ goto Exit;
+ }
+ if (EVP_PKEY_CTX_set_rsa_mgf1_md(pkey_ctx, scheme->scheme_md()) != 1) {
+ ret = PTLS_ERROR_LIBRARY;
+ goto Exit;
+ }
+ }
+ if (EVP_DigestVerifyUpdate(ctx, data.base, data.len) != 1) {
+ ret = PTLS_ERROR_LIBRARY;
+ goto Exit;
+ }
+ if (EVP_DigestVerifyFinal(ctx, signature.base, signature.len) != 1) {
+ ret = PTLS_ALERT_DECRYPT_ERROR;
+ goto Exit;
+ }
}
- if (EVP_DigestVerifyFinal(ctx, signature.base, signature.len) != 1) {
- ret = PTLS_ALERT_DECRYPT_ERROR;
- goto Exit;
- }
+
ret = 0;
Exit:
diff --git a/t/openssl.c b/t/openssl.c
index a6f0a06..5ca7bbf 100644
--- a/t/openssl.c
+++ b/t/openssl.c
@@ -138,7 +138,7 @@
uint8_t sigbuf_small[1024];
ptls_buffer_init(&sigbuf, sigbuf_small, sizeof(sigbuf_small));
- ok(do_sign(key, &sigbuf, ptls_iovec_init(message, strlen(message)), schemes[i].scheme_md()) == 0);
+ ok(do_sign(key, &sigbuf, ptls_iovec_init(message, strlen(message)), schemes[i].scheme_md != NULL ? schemes[i].scheme_md() : NULL) == 0);
EVP_PKEY_up_ref(key);
ok(verify_sign(key, schemes[i].scheme_id, ptls_iovec_init(message, strlen(message)),
ptls_iovec_init(sigbuf.base, sigbuf.off)) == 0);
@@ -180,6 +180,23 @@
#endif
}
+static void test_ed25519_sign(void)
+{
+#if defined EVP_PKEY_ED25519
+ EVP_PKEY *pkey = NULL;
+
+ { /* create pkey */
+ EVP_PKEY_CTX *pctx = EVP_PKEY_CTX_new_id(EVP_PKEY_ED25519, NULL);
+ EVP_PKEY_keygen_init(pctx);
+ EVP_PKEY_keygen(pctx, &pkey);
+ EVP_PKEY_CTX_free(pctx);
+ }
+
+ test_sign_verify(pkey, ed25519_signature_schemes);
+ EVP_PKEY_free(pkey);
+#endif
+}
+
static X509 *x509_from_pem(const char *pem)
{
BIO *bio = BIO_new_mem_buf((void *)pem, (int)strlen(pem));
@@ -318,6 +335,7 @@
subtest("rsa-sign", test_rsa_sign);
subtest("ecdsa-sign", test_ecdsa_sign);
+ subtest("ed25519-sign", test_ed25519_sign);
subtest("cert-verify", test_cert_verify);
subtest("picotls", test_picotls);
test_picotls_esni(esni_private_keys);