JSSE TlsPrfGenerator ArrayIndexOutOfBoundsException
Christopher Meyer
christopher.meyer at rub.de
Tue May 29 13:42:54 UTC 2012
Hi,
during some research we noticed an interesting implementation bug inside the
com.sun.crypto.provider.TlsPrfGenerator.expand(..) function.
The problem is that an internal for loop das some XOR magic on passed arrays:
for (int i = 0; i < secLen; i++) {
pad1[i] ^= secret[i + secOff];
pad2[i] ^= secret[i + secOff];
}
But nowhere is checked if the passed arrays are of a suitable length (at least
== secLen). We were able to get into a state where secLen is greather than
pad1.length and thus leading to an ArrayIndexOutOfBoundsException while
iterating.
This caused the SSLSocket to terminate (which is ok), but finally sending a
TLSv1 FATAL ALERT: internal_error where instead a TLSv1 FATAL ALERT:
handshake_failure should be returned.
>From developers point of view this seems to be a careless mistake, but from
cryptographers point of view these different error messages may give some
valuable hints on how the message was decrypted (chosen-ciphertext attacks).
The problem was found during research on Bleichenbacher's attack on SSL. A
non-conforming PKCS message with two 0x0 separation bytes in combination with
2048/4096 bit RSA keys will reproduce this scenario.
StackTraces (good/bad case) follow below:
how it should look like (1024 bit RSA keys):
--------------------------------------------
*** ClientKeyExchange, RSA PreMasterSecret, TLSv1
SESSION KEYGEN:
PreMaster Secret:
0000: 29 1B DD F3 23 2D 59 1F 65 17 93 EF 85 F3 1F 7F )...#-Y.e.......
0010: 69 BB FF C9 57 0B 67 4B 41 69 F9 CB 85 D9 71 D7 i...W.gKAi....q.
0020: 8F 63 71 C9 8D AB 00 03 01 E5 A5 8B BD 45 C4 99 .cq..........E..
0030: FF 5B F5 D2 DB A1 59 21 30 37 94 7C 2E 48 6A 8D .[....Y!07...Hj.
0040: 08 9B 5F 91 2E 1C 49 8E FD 6B E8 A2 56 8F 81 A7 .._...I..k..V...
0050: CD CD 10 4C 03 28 6B ...L.(k
RSA PreMasterSecret version error: expectedTLSv1 or TLSv1, decrypted:
Unknown-41.27
Generating new random premaster secret
SESSION KEYGEN:
PreMaster Secret:
0000: 03 01 E0 75 34 84 96 F2 CB 65 3E 09 C8 82 E3 38 ...u4....e>....8
0010: CA 1B 0E 85 6B 8A E5 BA 7F C5 51 ED F1 ED 4F 8F ....k.....Q...O.
0020: BFinalizer, called close()
3 59Finalizer, called closeInternal(true)
C3 C7 72 B2 17 53 55 F3 40 3B A9 4C 16 42 .Y..r..SU.@;.L.B
CONNECTION KEYGEN:
Client Nonce:
0000: 00 00 01 37 28 27 B6 E0 3E D5 6F 8D 3D D6 B0 D8 ...7('..>.o.=...
0010: 13 D2 62 75 2F 21 0C 6E 3D 76 B1 86 12 18 81 55 ..bu/!.n=v.....U
Server Nonce:
0000: 4F C4 CF B6 42 29 3C CD 97 44 C1 66 1A 5F 3B 5A O...B)<..D.f._;Z
0010: 3A EF 06 08 8A 48 E2 39 A8 42 0C 96 52 1F 7F 4F :....H.9.B..R..O
Master Secret:
0000: C3 8F 4D 51 9D 20 BB 17 42 0F 70 E2 C2 5E BB AA ..MQ. ..B.p..^..
0010: E2 55 45 BE D6 3D D3 11 B5 E7 59 E3 A1 26 EB 14 .UE..=....Y..&..
0020: FE 07 AF 80 6D 5A EC FB 11 12 CD EF 08 ED 31 7E ....mZ........1.
Client MAC write Secret:
0000: F6 0B 0B 73 6E FC CE 0A F3 64 F2 6C 5E D9 DF F2 ...sn....d.l^...
0010: A8 A4 98 22 ..."
Server MAC write Secret:
0000: D8 AC 63 54 F3 EA F6 55 C7 FE 08 70 FA 7D B8 32 ..cT...U...p...2
0010: 7A 21 4E 1B z!N.
Client write key:
0000: 43 22 FA 3A B2 80 CE 5E 37 41 8C 23 7D 40 28 5C C".:...^7A.#.@(\
Server write key:
0000: DF CF 6F CD 1F FD F4 37 E1 93 DE BF 89 16 6E 5F ..o....7......n_
Client write IV:
0000: DC 57 88 79 7B 78 B2 30 29 D4 3C 3F BF CB 01 57 .W.y.x.0).<?...W
Server write IV:
0000: EA A7 4B 01 69 C6 10 5B 41 E3 CD 58 95 26 A0 F2 ..K.i..[A..X.&..
Thread-2, READ: TLSv1 Change Cipher Spec, length = 1
Thread-2, READ: TLSv1 Handshake, length = 48
========>
========>
========> Thread-2, SEND TLSv1 ALERT: fatal, description = handshake_failure
========>
========>
Thread-2, WRITE: TLSv1 Alert, length = 2
Thread-2, called closeSocket()
Thread-2, handling exception: javax.net.ssl.SSLHandshakeException: Invalid
padding
javax.net.ssl.SSLHandshakeException: Invalid padding
at sun.security.ssl.Alerts.getSSLException(Alerts.java:192)
at sun.security.ssl.SSLSocketImpl.fatal(SSLSocketImpl.java:1697)
at sun.security.ssl.SSLSocketImpl.readRecord(SSLSocketImpl.java:904)
at
sun.security.ssl.SSLSocketImpl.performInitialHandshake(SSLSocketImpl.java:1190)
at sun.security.ssl.SSLSocketImpl.writeRecord(SSLSocketImpl.java:657)
at sun.security.ssl.AppOutputStream.write(AppOutputStream.java:108)
at java.io.OutputStream.write(OutputStream.java:75)
at
de.rub.nds.research.ssl.stack.tests.common.SSLServer.run(SSLServer.java:86)
at java.lang.Thread.run(Thread.java:679)
Caused by: javax.crypto.BadPaddingException: Padding length invalid: 55
at sun.security.ssl.CipherBox.removePadding(CipherBox.java:423)
at sun.security.ssl.CipherBox.decrypt(CipherBox.java:271)
at sun.security.ssl.InputRecord.decrypt(InputRecord.java:172)
at sun.security.ssl.SSLSocketImpl.readRecord(SSLSocketImpl.java:892)
... 6 more
how it looks when dealing with 2048, 4096 bit RSA keys:
-------------------------------------------------------
*** ClientKeyExchange, RSA PreMasterSecret, TLSv1
SESSION KEYGEN:
PreMaster Secret:
0000: 2B 05 89 91 6F F5 87 35 B9 8B 77 69 CF 83 8F CF +...o..5..wi....
0010: 6F 23 37 C9 E3 2F A9 51 C7 9D 3B 81 37 CB 61 F3 o#7../.Q..;.7.a.
0020: CB 29 21 E9 05 B7 73 8B 7F 6D 69 91 51 31 35 33 .)!...s..mi.Q153
0030: E5 03 A9 69 D3 23 9B 13 F3 4B 67 89 FD C9 9B 4D ...i.#...Kg....M
0040: A3 BB E5 AB 5D 85 D7 1D 79 8F 45 17 17 93 55 15 ....]...y.E...U.
0050: AD B7 17 33 CD 39 83 F7 6F 1F 4D EF A7 DD A5 55 ...3.9..o.M....U
0060: 0B A7 FB 99 33 09 00 03 01 1F EE 99 A8 6F C9 51 ....3........o.Q
0070: 7B 06 28 ED ED 34 84 65Finalizer, called close()
Finalizer, called closeInternal(true)
8B 7E 0A D3 05 57 1B E7 ..(..4.e.....W..
0080: CA 80 FC 34 6D A4 3D 9D B4 49 DB 85 24 71 3F CF ...4m.=..I..$q?.
0090: 8C E6 CA 63 1F 01 2A ...c..*
Thread-2, handling exception: java.lang.ArrayIndexOutOfBoundsException: 64
========>
========>
========> Thread-2, SEND TLSv1 ALERT: fatal, description = internal_error
========>
========>
Thread-2, WRITE: TLSv1 Alert, length = 2
Thread-2, called closeSocket()
javax.net.ssl.SSLException: java.lang.ArrayIndexOutOfBoundsException: 64
at sun.security.ssl.Alerts.getSSLException(Alerts.java:208)
at sun.security.ssl.SSLSocketImpl.fatal(SSLSocketImpl.java:1697)
at sun.security.ssl.SSLSocketImpl.fatal(SSLSocketImpl.java:1660)
at sun.security.ssl.SSLSocketImpl.handleException(SSLSocketImpl.java:1643)
at sun.security.ssl.SSLSocketImpl.handleException(SSLSocketImpl.java:1569)
at sun.security.ssl.AppOutputStream.write(AppOutputStream.java:113)
at java.io.OutputStream.write(OutputStream.java:75)
at
de.rub.nds.research.ssl.stack.tests.common.SSLServer.run(SSLServer.java:86)
at java.lang.Thread.run(Thread.java:679)
Caused by: java.lang.ArrayIndexOutOfBoundsException: 64
at com.sun.crypto.provider.TlsPrfGenerator.expand(TlsPrfGenerator.java:216)
at com.sun.crypto.provider.TlsPrfGenerator.doPRF(TlsPrfGenerator.java:187)
at com.sun.crypto.provider.TlsPrfGenerator.doPRF(TlsPrfGenerator.java:159)
at
com.sun.crypto.provider.TlsMasterSecretGenerator.engineGenerateKey(TlsMasterSecretGenerator.java:107)
at javax.crypto.KeyGenerator.generateKey(KeyGenerator.java:516)
at sun.security.ssl.Handshaker.calculateMasterSecret(Handshaker.java:769)
at sun.security.ssl.Handshaker.calculateKeys(Handshaker.java:732)
at
sun.security.ssl.ServerHandshaker.processMessage(ServerHandshaker.java:235)
at sun.security.ssl.Handshaker.processLoop(Handshaker.java:609)
at sun.security.ssl.Handshaker.process_record(Handshaker.java:545)
at sun.security.ssl.SSLSocketImpl.readRecord(SSLSocketImpl.java:945)
at
sun.security.ssl.SSLSocketImpl.performInitialHandshake(SSLSocketImpl.java:1190)
at sun.security.ssl.SSLSocketImpl.writeRecord(SSLSocketImpl.java:657)
at sun.security.ssl.AppOutputStream.write(AppOutputStream.java:108)
... 3 more
We only tested this with 1024, 2048, 4096 bit keys.
Maybe a simple length check inside the expand function could solve the issue.
Regards,
Chris
______________________________________
Dipl.-Ing. Christopher Meyer
Horst Görtz Institute for IT-Security
Chair for Network and Data Security
Ruhr-University Bochum, Germany
Universitätsstr. 150, ID 2/415
D-44801 Bochum, Germany
http:// www.nds.rub.de
Phone: (+49) (0)234 / 32 - 29815
Fax: (+49) (0)234 / 32 - 14347
More information about the security-dev
mailing list