Unknown ca after importing the client CA into the oracle wallet

I have an oracle database that has a server certificate signed by a root ca. I have a client that also has a client certificate that is signed by the same root CA.

I can configure a java application to open a TLS encrypted connection to the server when SSL_CLIENT_AUTHENTICATION is off. However, after I load the CA into the oracle wallet, and try to use the client cert/key to do mtls, the call fails with “unknown ca”

it seems to me that the server is still rejecting the client certificate even though the CA of the client is in the server’s trust store.

Run the oracle express database

podman run -d --name oracle-db --replace -p 1521:1521 -p 2484:2484 -p 1532:1532 -e ORACLE_PWD=password container-registry.oracle.com/database/express

Configure the certificate authority and certificates.

Step 1: Create a Certificate Authority

openssl genrsa -out ca-private-key.pem 2048
openssl req -x509 -new -nodes -key ca-private-key.pem -subj "/C=US/ST=State/L=Locality/O=Organization/CN=localhost" -out ca-cert.pem -days 3650
openssl genrsa -out oracle-private-key.pem 2048
openssl req -new -newkey rsa:2048 -nodes -keyout oracle-private-key.pem -out oracle-csr.pem -subj "/CN=0.0.0.0"

Step 3: Sign the CSR and Issue a Certificate

To sign the CSR and issue a certificate, you can use the openssl command to use the CA private key to sign the CSR.

openssl x509 -req -in oracle-csr.pem -CA ca-cert.pem -CAkey ca-private-key.pem -CAcreateserial -out oracle-cert.pem -days 3650

Step 4: Add the Certificate to the Oracle Wallet

Copy the certificates into the pod:

podman cp oracle-ssl/oracle-cert.pem oracle-db:cert.crt
podman cp oracle-ssl/server.key oracle-db:client.key

Exec into the pod to run the tls configuration.

podman exec -it oracle-db /bin/bash
export TCPS_CERTS_LOCATION=/home/oracle
/opt/oracle/configTcps.sh 1532 0.0.0.0 pass_word

Manually add the CA.

Step 5: Add the CA Authority to the Java Trust Store of the client.

To add the CA authority to the Java trust store, you can use the keytool command to import the CA certificate.

You can use the default truststore of the java runtime.

keytool -importcert -v -trustcacerts -alias myauthority -file ca-cert.pem -cacerts $JAVA_HOME/lib/security/cacerts -storepass changeitn

This will add the CA certificate to the Java trust store.

Test

openssl s_client -connect 0.0.0.0:1532 -CAfile ca/server_cert.pem

We can now see in the output that the server is presenting a certificate. That certificate is signed by a trusted ca with respect to us, the client.
We can see a succesfully established SSL session.

CONNECTED(00000003)
Can't use SSL_get_servername
depth=1 C = US, ST = State, L = Locality, O = Organization, CN = localhost
verify return:1
depth=0 CN = 0.0.0.0
verify return:1
---
Certificate chain
 0 s:CN = 0.0.0.0
   i:C = US, ST = State, L = Locality, O = Organization, CN = localhost
---
Server certificate
-----BEGIN CERTIFICATE-----
MIIC9DCCAdwCFFIj0zwc3kWP23kdU3Xu8sGESzaSMA0GCSqGSIb3DQEBCwUAMFsx
CzAJBgNVBAYTAlVTMQ4wDAYDVQQIDAVTdGF0ZTERMA8GA1UEBwwITG9jYWxpdHkx
FTATBgNVBAoMDE9yZ2FuaXphdGlvbjESMBAGA1UEAwwJbG9jYWxob3N0MB4XDTI0
MDkyMDE1MTMzNFoXDTM0MDkxODE1MTMzNFowEjEQMA4GA1UEAwwHMC4wLjAuMDCC
ASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAJ3++Gd/fubc1aHvcjer2+/Z
+9aJ/luA1Utg4n6HC92kh9jcC1DOTx2QLIU1ZRswsRIrrHqsTT7MWGL81WcBczx7
8ql97gL3tPwFxZgelXwu7nm/C4zy6tZJb08gkzRMQ6sqvXr4WrQCZDJxbqXXibwX
m/CEzOY4rAODowbuEXx1EusKf5NUu9p9yh0zJP5w8jZJLLipie7EQrBppPBhGyX0
4VD1N92QO9p4auJsx6H6H60Mak+KbbZU4r+01HZuUya2ooJg/5RGiLCm+NShcfYh
Yxqd5jKStE1X78AGcigyw5BqQcmKKP2cjqH8wbUlGRWv0MEjMgzcl36IuYAvUycC
AwEAATANBgkqhkiG9w0BAQsFAAOCAQEAfT0mwOMEylD3rYTznrYnobjYZjSPtMol
WSr8nf2NKrGJzSO0ziCPPyao2ea9ryvja7CHg+EnBDbnEO7N01jAPNPsaEU6O2Ry
vfWE+xeC7owshhVR+OKcy9vtJALR3R6sx0UiuYWX8CtsABwfv5S7ZUey5PGpNxV/
nwvKVU5TH7EpmxvEjYtHPKj32t/efEsr+IGakUmJzsgZvIVDiCnOKYZsk/1tx8Xi
e2DNsnLmTgpxqzeDWwfB9WbIRCv5hVgh3PxX+41D+2ktr+4MNw8VGYF6lWE9f+qK
S27mRUdy2N69l/TqhK9MtUJVzT1rrJOy6mp/uEpDaZPI8ezjSawACg==
-----END CERTIFICATE-----
subject=CN = 0.0.0.0

issuer=C = US, ST = State, L = Locality, O = Organization, CN = localhost

---
No client certificate CA names sent
Peer signing digest: SHA384
Peer signature type: RSA
Server Temp Key: ECDH, P-256, 256 bits
---
SSL handshake has read 1259 bytes and written 415 bytes
Verification: OK
---
New, TLSv1.2, Cipher is ECDHE-RSA-AES256-GCM-SHA384
Server public key is 2048 bit
Secure Renegotiation IS supported
Compression: NONE
Expansion: NONE
No ALPN negotiated
SSL-Session:
    Protocol  : TLSv1.2
    Cipher    : ECDHE-RSA-AES256-GCM-SHA384
    Session-ID: 85984CE01C015B7BCE54A5E27592358FAD096934067DD7DDB482534F3DD089EE
    Session-ID-ctx: 
    Master-Key: F1D08FF9E32D830D17A6909D10953577921D0F15C46280E8A88B294C9FB3076930CA5E28199DE5EE939CE162D66C62E8
    PSK identity: None
    PSK identity hint: None
    SRP username: None
    Start Time: 1727018204
    Timeout   : 7200 (sec)
    Verify return code: 0 (ok)
    Extended master secret: no

Turn SSL_CLIENT_AUTHENTICATION=TRUE

If we turn the parameter SSL_CLIENT_AUTHENTICATION=TRUE we will see the following error:

In the oracle trace

    
TNS-00542: SSL Handshake failed
    Oracle error 1: 28860
ORA-28860: Fatal SSL error
    nt secondary err code: 29024
    nt OS err code: 0
opiodr aborting process unknown ospid (4002) as a result of ORA-609
2024-09-20T15:41:56.282807+00:00
Errors in file /opt/oracle/diag/rdbms/xe/XE/trace/XE_ora_4002.trc:
ORA-00609: could not attach to incoming connection
ORA-28860: Fatal SSL error

In the Java trace:

"CertificateRequest": {
  "certificate types": [ecdsa_sign, rsa_sign, dss_sign]
  "supported signature algorithms": [ecdsa_secp256r1_sha256, ecdsa_secp384r1_sha384, ecdsa_secp521r1_sha512, rsa_pkcs1_sha256, rsa_pkcs1_sha384, rsa_pkcs1_sha512, dsa_sha256, ecdsa_sha224, rsa_sha224, dsa_sha224, ecdsa_sha1, rsa_pkcs1_sha1, dsa_sha1]
  "certificate authorities": []
}
)
javax.net.ssl|ALL|01|main|2024-09-20 17:41:56.265 CEST|X509Authentication.java:246|No X.509 cert selected for EC
javax.net.ssl|WARNING|01|main|2024-09-20 17:41:56.265 CEST|CertificateRequest.java:809|Unavailable authentication scheme: ecdsa_secp256r1_sha256
javax.net.ssl|ALL|01|main|2024-09-20 17:41:56.265 CEST|X509Authentication.java:246|No X.509 cert selected for EC
javax.net.ssl|WARNING|01|main|2024-09-20 17:41:56.265 CEST|CertificateRequest.java:809|Unavailable authentication scheme: ecdsa_secp384r1_sha384
javax.net.ssl|ALL|01|main|2024-09-20 17:41:56.265 CEST|X509Authentication.java:246|No X.509 cert selected for EC
javax.net.ssl|WARNING|01|main|2024-09-20 17:41:56.265 CEST|CertificateRequest.java:809|Unavailable authentication scheme: ecdsa_secp521r1_sha512
javax.net.ssl|ALL|01|main|2024-09-20 17:41:56.265 CEST|X509Authentication.java:246|No X.509 cert selected for RSA
javax.net.ssl|WARNING|01|main|2024-09-20 17:41:56.266 CEST|CertificateRequest.java:809|Unavailable authentication scheme: rsa_pkcs1_sha256
javax.net.ssl|ALL|01|main|2024-09-20 17:41:56.266 CEST|X509Authentication.java:246|No X.509 cert selected for RSA
javax.net.ssl|WARNING|01|main|2024-09-20 17:41:56.266 CEST|CertificateRequest.java:809|Unavailable authentication scheme: rsa_pkcs1_sha384
javax.net.ssl|ALL|01|main|2024-09-20 17:41:56.266 CEST|X509Authentication.java:246|No X.509 cert selected for RSA
javax.net.ssl|WARNING|01|main|2024-09-20 17:41:56.266 CEST|CertificateRequest.java:809|Unavailable authentication scheme: rsa_pkcs1_sha512
javax.net.ssl|ALL|01|main|2024-09-20 17:41:56.266 CEST|X509Authentication.java:246|No X.509 cert selected for DSA
javax.net.ssl|WARNING|01|main|2024-09-20 17:41:56.266 CEST|CertificateRequest.java:809|Unavailable authentication scheme: dsa_sha256
javax.net.ssl|ALL|01|main|2024-09-20 17:41:56.266 CEST|X509Authentication.java:246|No X.509 cert selected for EC
javax.net.ssl|WARNING|01|main|2024-09-20 17:41:56.266 CEST|CertificateRequest.java:809|Unavailable authentication scheme: ecdsa_sha224
javax.net.ssl|ALL|01|main|2024-09-20 17:41:56.267 CEST|X509Authentication.java:246|No X.509 cert selected for RSA
javax.net.ssl|WARNING|01|main|2024-09-20 17:41:56.267 CEST|CertificateRequest.java:809|Unavailable authentication scheme: rsa_sha224
javax.net.ssl|ALL|01|main|2024-09-20 17:41:56.267 CEST|X509Authentication.java:246|No X.509 cert selected for DSA
javax.net.ssl|WARNING|01|main|2024-09-20 17:41:56.267 CEST|CertificateRequest.java:809|Unavailable authentication scheme: dsa_sha224
javax.net.ssl|ALL|01|main|2024-09-20 17:41:56.267 CEST|X509Authentication.java:246|No X.509 cert selected for EC
javax.net.ssl|WARNING|01|main|2024-09-20 17:41:56.267 CEST|CertificateRequest.java:809|Unavailable authentication scheme: ecdsa_sha1
javax.net.ssl|ALL|01|main|2024-09-20 17:41:56.267 CEST|X509Authentication.java:246|No X.509 cert selected for RSA
javax.net.ssl|WARNING|01|main|2024-09-20 17:41:56.267 CEST|CertificateRequest.java:809|Unavailable authentication scheme: rsa_pkcs1_sha1
javax.net.ssl|ALL|01|main|2024-09-20 17:41:56.267 CEST|X509Authentication.java:246|No X.509 cert selected for DSA
javax.net.ssl|WARNING|01|main|2024-09-20 17:41:56.267 CEST|CertificateRequest.java:809|Unavailable authentication scheme: dsa_sha1
javax.net.ssl|WARNING|01|main|2024-09-20 17:41:56.267 CEST|CertificateRequest.java:819|No available authentication scheme
javax.net.ssl|DEBUG|01|main|2024-09-20 17:41:56.268 CEST|ServerHelloDone.java:151|Consuming ServerHelloDone handshake message (
<empty>
)
javax.net.ssl|DEBUG|01|main|2024-09-20 17:41:56.268 CEST|CertificateMessage.java:299|No X.509 certificate for client authentication, use empty Certificate message instead
javax.net.ssl|DEBUG|01|main|2024-09-20 17:41:56.268 CEST|CertificateMessage.java:330|Produced client Certificate handshake message (
"Certificates": <empty list>
)
javax.net.ss

Client authentication

We first need to create a certificate and key for our client.

openssl req -newkey rsa:2048 -keyout client-key.pem -out client-csr.pem -nodes -subj "/CN=Client"

Then we can create a CSR for the certificate.

openssl req -new -key client-key.pem -out client-csr.pem

We sign the certificate using the CA’s private key.

openssl x509 -req -in client-csr.pem -CA ../ca/ca-cert.pem -CAkey ../ca/ca-private-key.pem -CAcreateserial -out client-cert.pem -days 365

We then need to import the certificate into the truststore of our java runtime.

openssl pkcs12 -export -in client.crt -inkey client.key -out client.p12 -name client-cert

keytool -importkeystore -deststorepass changeit -destkeypass changeit -destkeystore $JAVA_HOME/lib/security/cacerts -srckeystore client/client.p12 -srcstoretype PKCS12  -srcstorepass password -alias client-cert 

We can then try to run out application:

/home/pat/.sdkman/candidates/java/11.0.23-sem/bin/java -Djavax.net.debug=all -Djavax.net.ssl.keyStore=java/mykeystore.jks -Djavax.net.ssl.keyStorePassword=password -javaagent:/home/pat/.local/share/idea-ce/lib/idea_rt.jar=38277:/home/pat/.local/share/idea-ce/bin -Dfile.encoding=UTF-8 -classpath /home/pat/Projects/clients/blm/oracle-ssl/target/classes:/home/pat/.m2/repository/com/oracle/database/jdbc/ojdbc8/19.8.0.0/ojdbc8-19.8.0.0.jar org.ibm.OracleConnection

Copy the root certificate into the pod
podman cp ca/ca-cert.pem oracle-db:ca-cert.pem

Add the trusted cert to the wallet and restart the listener
orapki wallet add -wallet ${ORACLE_BASE}/oradata/clientWallet/${ORACLE_SID} -trusted_cert -cert /home/oracle/ca-cert.pem

At this point I expect that everything should be fine – server has ROOT CA to verify the client certificate. I see this in my client logs:

javax.net.ssl|DEBUG|01|main|2024-09-23 09:29:17.061 CEST|ServerHelloDone.java:151|Consuming ServerHelloDone handshake message (
<empty>
)
javax.net.ssl|DEBUG|01|main|2024-09-23 09:29:17.061 CEST|CertificateMessage.java:330|Produced client Certificate handshake message (
"Certificates": [
  "certificate" : {
    "version"            : "v1",
    "serial number"      : "52 23 D3 3C 1C DE 45 8F DB 79 1D 53 75 EE F2 C1 84 4B 36 96",
    "signature algorithm": "SHA256withRSA",
    "issuer"             : "CN=localhost, O=Organization, L=Locality, ST=State, C=US",
    "not before"         : "2024-09-23 09:15:51.000 CEST",
    "not  after"         : "2025-09-23 09:15:51.000 CEST",
    "subject"            : "[email protected], CN=localhost, OU=IBM, O=IBM, L=New York, ST=New York, C=US",
    "subject public key" : "RSA"}
]
)

but then i see this:

javax.net.ssl|DEBUG|01|main|2024-09-23 09:29:17.074 CEST|SSLEngineInputRecord.java:214|READ: TLSv1.2 alert, length = 2
javax.net.ssl|DEBUG|01|main|2024-09-23 09:29:17.074 CEST|Alert.java:238|Received alert message (
"Alert": {
  "level"      : "fatal",
  "description": "unknown_ca"
}
)
javax.net.ssl|ERROR|01|main|2024-09-23 09:29:17.075 CEST|TransportContext.java:352|Fatal (UNKNOWN_CA): Received fatal alert: unknown_ca (
"throwable" : {
  javax.net.ssl.SSLHandshakeException: Received fatal alert: unknown_ca
    at java.base/sun.security.ssl.Alert.createSSLException(Alert.java:131)
    at java.base/sun.security.ssl.Alert.createSSLException(Alert.java:117)
    at java.base/sun.security.ssl.TransportContext.fatal(TransportContext.java:347)
    at java.base/sun.security.ssl.Alert$AlertConsumer.consume(Alert.java:293)
    at java.base/sun.security.ssl.TransportContext.dispatch(TransportContext.java:186)
    at java.base/sun.security.ssl.SSLTransport.decode(SSLTransport.java:172)
    at java.base/sun.security.ssl.SSLEngineImpl.decode(SSLEngineImpl.java:681)
    at java.base/sun.security.ssl.SSLEngineImpl.readReco

I know the CA is in the client side trust store so i assume this is coming from the server, but its not clear from the logs.

Trang chủ Giới thiệu Sinh nhật bé trai Sinh nhật bé gái Tổ chức sự kiện Biểu diễn giải trí Dịch vụ khác Trang trí tiệc cưới Tổ chức khai trương Tư vấn dịch vụ Thư viện ảnh Tin tức - sự kiện Liên hệ Chú hề sinh nhật Trang trí YEAR END PARTY công ty Trang trí tất niên cuối năm Trang trí tất niên xu hướng mới nhất Trang trí sinh nhật bé trai Hải Đăng Trang trí sinh nhật bé Khánh Vân Trang trí sinh nhật Bích Ngân Trang trí sinh nhật bé Thanh Trang Thuê ông già Noel phát quà Biểu diễn xiếc khỉ Xiếc quay đĩa Dịch vụ tổ chức sự kiện 5 sao Thông tin về chúng tôi Dịch vụ sinh nhật bé trai Dịch vụ sinh nhật bé gái Sự kiện trọn gói Các tiết mục giải trí Dịch vụ bổ trợ Tiệc cưới sang trọng Dịch vụ khai trương Tư vấn tổ chức sự kiện Hình ảnh sự kiện Cập nhật tin tức Liên hệ ngay Thuê chú hề chuyên nghiệp Tiệc tất niên cho công ty Trang trí tiệc cuối năm Tiệc tất niên độc đáo Sinh nhật bé Hải Đăng Sinh nhật đáng yêu bé Khánh Vân Sinh nhật sang trọng Bích Ngân Tiệc sinh nhật bé Thanh Trang Dịch vụ ông già Noel Xiếc thú vui nhộn Biểu diễn xiếc quay đĩa Dịch vụ tổ chức tiệc uy tín Khám phá dịch vụ của chúng tôi Tiệc sinh nhật cho bé trai Trang trí tiệc cho bé gái Gói sự kiện chuyên nghiệp Chương trình giải trí hấp dẫn Dịch vụ hỗ trợ sự kiện Trang trí tiệc cưới đẹp Khởi đầu thành công với khai trương Chuyên gia tư vấn sự kiện Xem ảnh các sự kiện đẹp Tin mới về sự kiện Kết nối với đội ngũ chuyên gia Chú hề vui nhộn cho tiệc sinh nhật Ý tưởng tiệc cuối năm Tất niên độc đáo Trang trí tiệc hiện đại Tổ chức sinh nhật cho Hải Đăng Sinh nhật độc quyền Khánh Vân Phong cách tiệc Bích Ngân Trang trí tiệc bé Thanh Trang Thuê dịch vụ ông già Noel chuyên nghiệp Xem xiếc khỉ đặc sắc Xiếc quay đĩa thú vị
Trang chủ Giới thiệu Sinh nhật bé trai Sinh nhật bé gái Tổ chức sự kiện Biểu diễn giải trí Dịch vụ khác Trang trí tiệc cưới Tổ chức khai trương Tư vấn dịch vụ Thư viện ảnh Tin tức - sự kiện Liên hệ Chú hề sinh nhật Trang trí YEAR END PARTY công ty Trang trí tất niên cuối năm Trang trí tất niên xu hướng mới nhất Trang trí sinh nhật bé trai Hải Đăng Trang trí sinh nhật bé Khánh Vân Trang trí sinh nhật Bích Ngân Trang trí sinh nhật bé Thanh Trang Thuê ông già Noel phát quà Biểu diễn xiếc khỉ Xiếc quay đĩa
Thiết kế website Thiết kế website Thiết kế website Cách kháng tài khoản quảng cáo Mua bán Fanpage Facebook Dịch vụ SEO Tổ chức sinh nhật