-
Bug
-
Resolution: Fixed
-
P4
-
8, 11, 12
-
b05
-
x86_64
-
generic
-
Verified
ADDITIONAL SYSTEM INFORMATION :
# jdk-12/bin/java -version
openjdk version "12-ea" 2019-03-19
OpenJDK Runtime Environment (build 12-ea+23)
OpenJDK 64-Bit Server VM (build 12-ea+23, mixed mode, sharing)
# uname -a
Linux foo.bar.com 3.10.0-327.18.2.el7.x86_64 #1 SMP Thu May 12 11:03:55 UTC 2016 x86_64 x86_64 x86_64 GNU/Linux
# cat /etc/redhat-release
CentOS Linux release 7.2.1511 (Core)
The bug is present in Java releases at least as far back as 1.8.0_181
A DESCRIPTION OF THE PROBLEM :
When two or more certificate entries have the exact same distinguished name but yet are distinct entities, keytool's importkeystore operation may mix up the entries in the certificate chain. Trying to use such a migrated keystore for TLS communication results in a certificate path error for obvious reasons. It's as if DNs are being consulted to reconstruct the certificates in a chain. If the chain's array couldn't be copy over intact for whatever reason, KeyIdentifiers would be more reliable than distinguished names when reconstructing the chains. Not every cert out there has SubjectKeyIdentifier and AuthorityKeyIdentifier extensions but if a cert has it, that would be preferable over the DN.
STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
Start out with a jceks keystore with multiple entries for example: ca1, ca2, server1, server2. Where server1 is signed by ca1, server2 is signed by ca2, and ca1 has the same DN as ca2.
(I suppose having more DN collisions would increase the chances of having the cert chains mixed up)
Then migrate the JceKS keystore to PKCS12 like so:
keytool -importkeystore -srckeystore mykeystore -destkeystore mykeystore -deststoretype pkcs12
EXPECTED VERSUS ACTUAL BEHAVIOR :
EXPECTED -
Expect server1's chain to consist of the following certs: server1, ca1
For example, listing the alias on the original (JceKS) keystore. Note how server1's AuthorityKeyIdentifier matches the SubjectKeyIdentifier of the next cert in the chain:
# jdk-12/bin/keytool -keystore mykeystore.old -list -alias server1 -v
Alias name: server1
Creation date: Dec 11, 2018
Entry type: PrivateKeyEntry
Certificate chain length: 2
Certificate[1]:
Owner: CN=server1
Issuer: CN=Foo CA
Serial number: 813e54f2fe6
...
Certificate fingerprints:
SHA1: 42:25:3D:E2:90:D9:D6:F5:24:08:66:A5:E4:16:44:71:67:D4:B4:35
SHA256: 84:35:9A:08:61:C5:82:FD:F1:E9:A9:59:CE:DC:26:59:FC:14:44:BA:DB:2D:83:90:E8:89:BA:A5:3E:E5:49:8F
Signature algorithm name: SHA384withRSA
Subject Public Key Algorithm: 2048-bit RSA key
Version: 3
Extensions:
...
#2: ObjectId: 2.5.29.35 Criticality=false
AuthorityKeyIdentifier [
KeyIdentifier [
0000: 3F CD F0 65 62 51 1C 72 2A 24 DD 61 3C 2B 88 D3 ?..ebQ.r*$.a<+..
0010: 5F E8 CE 61 _..a
]
SerialNumber: [ b3a3897b 9b]
]
...
#7: ObjectId: 2.5.29.14 Criticality=false
SubjectKeyIdentifier [
KeyIdentifier [
0000: D4 8D D2 BF 45 4C 7D CD 9C F2 5B 71 2C 1D 5B 89 ....EL....[q,.[.
0010: B0 03 1D 73 ...s
]
]
Certificate[2]:
Owner: CN=Foo CA
Issuer: CN=Foo CA
Serial number: b3a3897b9b
...
Certificate fingerprints:
SHA1: 25:CA:CA:A4:00:5F:65:BD:AF:A6:9E:02:FB:E4:F4:0C:B9:B4:0A:07
SHA256: 7E:C3:B4:AD:3D:0C:3A:2F:FB:AE:4F:3F:22:57:AC:1A:2B:DE:03:02:EC:BA:88:BD:24:4C:B9:71:93:93:D1:F5
Signature algorithm name: SHA384withRSA
Subject Public Key Algorithm: 2048-bit RSA key
Version: 3
Extensions:
#1: ObjectId: 2.5.29.35 Criticality=false
AuthorityKeyIdentifier [
KeyIdentifier [
0000: 3F CD F0 65 62 51 1C 72 2A 24 DD 61 3C 2B 88 D3 ?..ebQ.r*$.a<+..
0010: 5F E8 CE 61 _..a
]
SerialNumber: [ b3a3897b 9b]
]
...
#4: ObjectId: 2.5.29.14 Criticality=false
SubjectKeyIdentifier [
KeyIdentifier [
0000: 3F CD F0 65 62 51 1C 72 2A 24 DD 61 3C 2B 88 D3 ?..ebQ.r*$.a<+..
0010: 5F E8 CE 61 _..a
]
]
Warning:
The JCEKS keystore uses a proprietary format. It is recommended to migrate to PKCS12 which is an industry standard format using "keytool -importkeystore -srckeystore mykeystore -destkeystore mykeystore -deststoretype pkcs12".
ACTUAL -
server1's chain actually consists of the following certs: server1, ca2
For example, listing the alias on the migrated (PKCS12) keystore. Note how server1's AuthorityKeyIdentifier does not match the SubjectKeyIdentifier of the next cert in the chain:
# jdk-12/bin/keytool -keystore mykeystore -list -alias server1 -v
Alias name: server1
Creation date: Dec 12, 2018
Entry type: PrivateKeyEntry
Certificate chain length: 2
Certificate[1]:
Owner: CN=server1
Issuer: CN=Foo CA
Serial number: 813e54f2fe6
...
Certificate fingerprints:
SHA1: 42:25:3D:E2:90:D9:D6:F5:24:08:66:A5:E4:16:44:71:67:D4:B4:35
SHA256: 84:35:9A:08:61:C5:82:FD:F1:E9:A9:59:CE:DC:26:59:FC:14:44:BA:DB:2D:83:90:E8:89:BA:A5:3E:E5:49:8F
Signature algorithm name: SHA384withRSA
Subject Public Key Algorithm: 2048-bit RSA key
Version: 3
Extensions:
...
#2: ObjectId: 2.5.29.35 Criticality=false
AuthorityKeyIdentifier [
KeyIdentifier [
0000: 3F CD F0 65 62 51 1C 72 2A 24 DD 61 3C 2B 88 D3 ?..ebQ.r*$.a<+..
0010: 5F E8 CE 61 _..a
]
SerialNumber: [ b3a3897b 9b]
]
...
#7: ObjectId: 2.5.29.14 Criticality=false
SubjectKeyIdentifier [
KeyIdentifier [
0000: D4 8D D2 BF 45 4C 7D CD 9C F2 5B 71 2C 1D 5B 89 ....EL....[q,.[.
0010: B0 03 1D 73 ...s
]
]
Certificate[2]:
Owner: CN=Foo CA
Issuer: CN=Foo CA
Serial number: b3a3897b9f
...
Certificate fingerprints:
SHA1: 83:EF:75:42:77:86:9A:20:0A:22:2F:E2:98:03:64:14:32:EF:B0:08
SHA256: FF:CA:D5:A9:6C:33:57:64:52:19:C2:B1:C3:6B:51:14:F0:7D:AC:9F:6D:62:15:23:72:E7:21:4D:54:A6:6D:B1
Signature algorithm name: SHA384withECDSA
Subject Public Key Algorithm: 384-bit EC (secp384r1) key
Version: 3
Extensions:
#1: ObjectId: 2.5.29.35 Criticality=false
AuthorityKeyIdentifier [
KeyIdentifier [
0000: 87 D3 37 C4 FB 74 F3 46 AC 64 87 2B 55 1A 43 A5 ..7..t.F.d.+U.C.
0010: CE 7F 80 0F ....
]
SerialNumber: [ b3a3897b 9f]
]
...
#4: ObjectId: 2.5.29.14 Criticality=false
SubjectKeyIdentifier [
KeyIdentifier [
0000: 87 D3 37 C4 FB 74 F3 46 AC 64 87 2B 55 1A 43 A5 ..7..t.F.d.+U.C.
0010: CE 7F 80 0F ....
]
]
FREQUENCY : often
# jdk-12/bin/java -version
openjdk version "12-ea" 2019-03-19
OpenJDK Runtime Environment (build 12-ea+23)
OpenJDK 64-Bit Server VM (build 12-ea+23, mixed mode, sharing)
# uname -a
Linux foo.bar.com 3.10.0-327.18.2.el7.x86_64 #1 SMP Thu May 12 11:03:55 UTC 2016 x86_64 x86_64 x86_64 GNU/Linux
# cat /etc/redhat-release
CentOS Linux release 7.2.1511 (Core)
The bug is present in Java releases at least as far back as 1.8.0_181
A DESCRIPTION OF THE PROBLEM :
When two or more certificate entries have the exact same distinguished name but yet are distinct entities, keytool's importkeystore operation may mix up the entries in the certificate chain. Trying to use such a migrated keystore for TLS communication results in a certificate path error for obvious reasons. It's as if DNs are being consulted to reconstruct the certificates in a chain. If the chain's array couldn't be copy over intact for whatever reason, KeyIdentifiers would be more reliable than distinguished names when reconstructing the chains. Not every cert out there has SubjectKeyIdentifier and AuthorityKeyIdentifier extensions but if a cert has it, that would be preferable over the DN.
STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
Start out with a jceks keystore with multiple entries for example: ca1, ca2, server1, server2. Where server1 is signed by ca1, server2 is signed by ca2, and ca1 has the same DN as ca2.
(I suppose having more DN collisions would increase the chances of having the cert chains mixed up)
Then migrate the JceKS keystore to PKCS12 like so:
keytool -importkeystore -srckeystore mykeystore -destkeystore mykeystore -deststoretype pkcs12
EXPECTED VERSUS ACTUAL BEHAVIOR :
EXPECTED -
Expect server1's chain to consist of the following certs: server1, ca1
For example, listing the alias on the original (JceKS) keystore. Note how server1's AuthorityKeyIdentifier matches the SubjectKeyIdentifier of the next cert in the chain:
# jdk-12/bin/keytool -keystore mykeystore.old -list -alias server1 -v
Alias name: server1
Creation date: Dec 11, 2018
Entry type: PrivateKeyEntry
Certificate chain length: 2
Certificate[1]:
Owner: CN=server1
Issuer: CN=Foo CA
Serial number: 813e54f2fe6
...
Certificate fingerprints:
SHA1: 42:25:3D:E2:90:D9:D6:F5:24:08:66:A5:E4:16:44:71:67:D4:B4:35
SHA256: 84:35:9A:08:61:C5:82:FD:F1:E9:A9:59:CE:DC:26:59:FC:14:44:BA:DB:2D:83:90:E8:89:BA:A5:3E:E5:49:8F
Signature algorithm name: SHA384withRSA
Subject Public Key Algorithm: 2048-bit RSA key
Version: 3
Extensions:
...
#2: ObjectId: 2.5.29.35 Criticality=false
AuthorityKeyIdentifier [
KeyIdentifier [
0000: 3F CD F0 65 62 51 1C 72 2A 24 DD 61 3C 2B 88 D3 ?..ebQ.r*$.a<+..
0010: 5F E8 CE 61 _..a
]
SerialNumber: [ b3a3897b 9b]
]
...
#7: ObjectId: 2.5.29.14 Criticality=false
SubjectKeyIdentifier [
KeyIdentifier [
0000: D4 8D D2 BF 45 4C 7D CD 9C F2 5B 71 2C 1D 5B 89 ....EL....[q,.[.
0010: B0 03 1D 73 ...s
]
]
Certificate[2]:
Owner: CN=Foo CA
Issuer: CN=Foo CA
Serial number: b3a3897b9b
...
Certificate fingerprints:
SHA1: 25:CA:CA:A4:00:5F:65:BD:AF:A6:9E:02:FB:E4:F4:0C:B9:B4:0A:07
SHA256: 7E:C3:B4:AD:3D:0C:3A:2F:FB:AE:4F:3F:22:57:AC:1A:2B:DE:03:02:EC:BA:88:BD:24:4C:B9:71:93:93:D1:F5
Signature algorithm name: SHA384withRSA
Subject Public Key Algorithm: 2048-bit RSA key
Version: 3
Extensions:
#1: ObjectId: 2.5.29.35 Criticality=false
AuthorityKeyIdentifier [
KeyIdentifier [
0000: 3F CD F0 65 62 51 1C 72 2A 24 DD 61 3C 2B 88 D3 ?..ebQ.r*$.a<+..
0010: 5F E8 CE 61 _..a
]
SerialNumber: [ b3a3897b 9b]
]
...
#4: ObjectId: 2.5.29.14 Criticality=false
SubjectKeyIdentifier [
KeyIdentifier [
0000: 3F CD F0 65 62 51 1C 72 2A 24 DD 61 3C 2B 88 D3 ?..ebQ.r*$.a<+..
0010: 5F E8 CE 61 _..a
]
]
Warning:
The JCEKS keystore uses a proprietary format. It is recommended to migrate to PKCS12 which is an industry standard format using "keytool -importkeystore -srckeystore mykeystore -destkeystore mykeystore -deststoretype pkcs12".
ACTUAL -
server1's chain actually consists of the following certs: server1, ca2
For example, listing the alias on the migrated (PKCS12) keystore. Note how server1's AuthorityKeyIdentifier does not match the SubjectKeyIdentifier of the next cert in the chain:
# jdk-12/bin/keytool -keystore mykeystore -list -alias server1 -v
Alias name: server1
Creation date: Dec 12, 2018
Entry type: PrivateKeyEntry
Certificate chain length: 2
Certificate[1]:
Owner: CN=server1
Issuer: CN=Foo CA
Serial number: 813e54f2fe6
...
Certificate fingerprints:
SHA1: 42:25:3D:E2:90:D9:D6:F5:24:08:66:A5:E4:16:44:71:67:D4:B4:35
SHA256: 84:35:9A:08:61:C5:82:FD:F1:E9:A9:59:CE:DC:26:59:FC:14:44:BA:DB:2D:83:90:E8:89:BA:A5:3E:E5:49:8F
Signature algorithm name: SHA384withRSA
Subject Public Key Algorithm: 2048-bit RSA key
Version: 3
Extensions:
...
#2: ObjectId: 2.5.29.35 Criticality=false
AuthorityKeyIdentifier [
KeyIdentifier [
0000: 3F CD F0 65 62 51 1C 72 2A 24 DD 61 3C 2B 88 D3 ?..ebQ.r*$.a<+..
0010: 5F E8 CE 61 _..a
]
SerialNumber: [ b3a3897b 9b]
]
...
#7: ObjectId: 2.5.29.14 Criticality=false
SubjectKeyIdentifier [
KeyIdentifier [
0000: D4 8D D2 BF 45 4C 7D CD 9C F2 5B 71 2C 1D 5B 89 ....EL....[q,.[.
0010: B0 03 1D 73 ...s
]
]
Certificate[2]:
Owner: CN=Foo CA
Issuer: CN=Foo CA
Serial number: b3a3897b9f
...
Certificate fingerprints:
SHA1: 83:EF:75:42:77:86:9A:20:0A:22:2F:E2:98:03:64:14:32:EF:B0:08
SHA256: FF:CA:D5:A9:6C:33:57:64:52:19:C2:B1:C3:6B:51:14:F0:7D:AC:9F:6D:62:15:23:72:E7:21:4D:54:A6:6D:B1
Signature algorithm name: SHA384withECDSA
Subject Public Key Algorithm: 384-bit EC (secp384r1) key
Version: 3
Extensions:
#1: ObjectId: 2.5.29.35 Criticality=false
AuthorityKeyIdentifier [
KeyIdentifier [
0000: 87 D3 37 C4 FB 74 F3 46 AC 64 87 2B 55 1A 43 A5 ..7..t.F.d.+U.C.
0010: CE 7F 80 0F ....
]
SerialNumber: [ b3a3897b 9f]
]
...
#4: ObjectId: 2.5.29.14 Criticality=false
SubjectKeyIdentifier [
KeyIdentifier [
0000: 87 D3 37 C4 FB 74 F3 46 AC 64 87 2B 55 1A 43 A5 ..7..t.F.d.+U.C.
0010: CE 7F 80 0F ....
]
]
FREQUENCY : often