diff --git a/rsa.go b/rsa.go index 5aef65b8..89a358ad 100644 --- a/rsa.go +++ b/rsa.go @@ -384,14 +384,28 @@ 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 - }{ + } + + 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 := 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)