From e417598b0b2a0fd0ef7d89e3ede288fec71e74c2 Mon Sep 17 00:00:00 2001 From: Daiki Ueno Date: Thu, 1 Feb 2024 15:33:16 +0900 Subject: [PATCH] rsa: Allow omission of precomputed values in NewPrivateKeyRSA OpenSSL 3.0 and 3.1 required precomputed values for CRT (Dp, Dq, and Qinv), when the primes (P and Q) are included in the params array. Since all of them can be derived from N, E, and D, this patch simply stops passing those values if any of them are missing. See also: https://github.com/openssl/openssl/pull/22334 Signed-off-by: Daiki Ueno --- rsa.go | 24 ++++++++++++++++++++---- rsa_test.go | 2 ++ 2 files changed, 22 insertions(+), 4 deletions(-) diff --git a/rsa.go b/rsa.go index 5aef65b8..f28d323a 100644 --- a/rsa.go +++ b/rsa.go @@ -384,14 +384,30 @@ func newRSAKey3(isPriv bool, N, E, D, P, Q, Dp, Dq, Qinv BigInt) (C.GO_EVP_PKEY_ return nil, newOpenSSLError("OSSL_PARAM_BLD_new") } defer C.go_openssl_OSSL_PARAM_BLD_free(bld) - var comps = [...]struct { + + type bigIntParam struct{ name *C.char num BigInt - }{ + } + + comps := make([]bigIntParam, 0, 8) + + required := [...]bigIntParam{ {paramRSA_N, N}, {paramRSA_E, E}, {paramRSA_D, D}, - {paramRSA_P, P}, {paramRSA_Q, Q}, - {paramRSA_Dp, Dp}, {paramRSA_Dq, Dq}, {paramRSA_Qinv, Qinv}, } + comps = append(comps, required[:]...) + + // OpenSSL 3.0 and 3.1 required all the precomputed values if + // P and Q are present. See: + // https://github.com/openssl/openssl/pull/22334 + if P != nil && Q != nil && Dp != nil && Dq != nil && Qinv != nil { + precomputed := [...]bigIntParam{ + {paramRSA_P, P}, {paramRSA_Q, Q}, + {paramRSA_Dp, Dp}, {paramRSA_Dq, Dq}, {paramRSA_Qinv, Qinv}, + } + comps = append(comps, precomputed[:]...) + } + for _, comp := range comps { if comp.num == nil { continue diff --git a/rsa_test.go b/rsa_test.go index c926e9cf..1d2c2cab 100644 --- a/rsa_test.go +++ b/rsa_test.go @@ -217,6 +217,8 @@ func newRSAKey(t *testing.T, size int) (*openssl.PrivateKeyRSA, *openssl.PublicK if err != nil { t.Fatalf("GenerateKeyRSA(%d): %v", size, err) } + // Exercise omission of precomputed value + Dp = nil priv, err := openssl.NewPrivateKeyRSA(N, E, D, P, Q, Dp, Dq, Qinv) if err != nil { t.Fatalf("NewPrivateKeyRSA(%d): %v", size, err)