SSLHandshakeException after deleting SHA1 certificate: Received fatal warning: bad_certificate. Server log: SEC_ERROR_REUSED_ISSUER_AND_SERIAL

Our Java Swing + Visual Basic APP allows users to authenticate to the server using an SSL connection. Now, two users from the same entity client sharing a smart card suddenly encounter a problem: they cannot connect to the server with the Java part, but with VB modules this is fine.

On the server side, we used to have both ancert SHA1 and SHA256 root. When the server admins removed the ANCERT SHA1 root and sub-root certificates, we had a problem with "bad_certificate".

After we -Djavax.net.debug=all

finally added the generated log, we see that the error occurs after CertificateVerify

and Client Finish

:

...
*** CertificateVerify
[write] MD5 and SHA1 hashes:  len = 262
0000: 0F 00 01 02 01 00 0C F5   8A 0A 9C 38 E9 6B E4 B6  ...........8.k..
0010: AC 2D 35 26 61 E3 56 72   66 DE B9 E0 AE CD B2 7B  .-5&a.Vrf.......
0020: 41 AF EB 66 9B 48 05 11   94 75 0D 0F 01 4B CA E6  A..f.H...u...K..
0030: 64 60 B7 5D 85 5D 61 1B   EA 7F 38 F1 5D D4 91 AE  d`.].]a...8.]...
0040: 04 84 19 3A 76 75 1E 87   4D C7 42 AB 16 9E 07 AD  ...:vu..M.B.....
0050: 7D 60 9A A2 A8 94 B9 2F   08 79 40 AA 96 14 2E F4  .`...../.y@.....
0060: 88 CA 72 00 46 8F EF D5   A2 6D 6B 7C B9 99 44 52  ..r.F....mk...DR
0070: FB CA F8 F8 00 D1 95 5E   15 B9 AD C6 1B 51 71 FB  .......^.....Qq.
0080: 6E 34 17 EC 0D D0 1B 8E   49 D7 DF F0 96 82 E6 27  n4......I......'
0090: F7 1B 2B 39 42 D5 CE 92   30 27 E5 07 7D 6C 87 6F  ..+9B...0'...l.o
00A0: CE CD 81 DD 8A 04 D6 F2   EE 36 D4 2D FC 3B 00 58  .........6.-.;.X
00B0: 93 D5 85 D9 EB C4 DC 30   FC 91 E5 CB 44 8B 6A A2  .......0....D.j.
00C0: 38 96 DD 21 B0 C5 C3 27   34 FC 55 97 00 26 5F 17  8..!...'4.U..&_.
00D0: F3 53 05 45 23 81 00 C2   36 FC C1 0B B7 45 8B 87  .S.E#...6....E..
00E0: 61 F1 21 65 AA F6 34 B4   15 85 AF A5 B2 21 C3 65  a.!e..4......!.e
00F0: 7E 9D B1 F3 F8 13 8D 58   14 1A F1 CE 9A 7F 53 6C  .......X......Sl
0100: 6F 96 A3 77 8F 9F                                  o..w..
Thread-7, WRITE: TLSv1.1 Handshake, length = 262
[Raw write]: length = 267
0000: 16 03 02 01 06 0F 00 01   02 01 00 0C F5 8A 0A 9C  ................
0010: 38 E9 6B E4 B6 AC 2D 35   26 61 E3 56 72 66 DE B9  8.k...-5&a.Vrf..
0020: E0 AE CD B2 7B 41 AF EB   66 9B 48 05 11 94 75 0D  .....A..f.H...u.
0030: 0F 01 4B CA E6 64 60 B7   5D 85 5D 61 1B EA 7F 38  ..K..d`.].]a...8
0040: F1 5D D4 91 AE 04 84 19   3A 76 75 1E 87 4D C7 42  .]......:vu..M.B
0050: AB 16 9E 07 AD 7D 60 9A   A2 A8 94 B9 2F 08 79 40  ......`...../.y@
0060: AA 96 14 2E F4 88 CA 72   00 46 8F EF D5 A2 6D 6B  .......r.F....mk
0070: 7C B9 99 44 52 FB CA F8   F8 00 D1 95 5E 15 B9 AD  ...DR.......^...
0080: C6 1B 51 71 FB 6E 34 17   EC 0D D0 1B 8E 49 D7 DF  ..Qq.n4......I..
0090: F0 96 82 E6 27 F7 1B 2B   39 42 D5 CE 92 30 27 E5  ....'..+9B...0'.
00A0: 07 7D 6C 87 6F CE CD 81   DD 8A 04 D6 F2 EE 36 D4  ..l.o.........6.
00B0: 2D FC 3B 00 58 93 D5 85   D9 EB C4 DC 30 FC 91 E5  -.;.X.......0...
00C0: CB 44 8B 6A A2 38 96 DD   21 B0 C5 C3 27 34 FC 55  .D.j.8..!...'4.U
00D0: 97 00 26 5F 17 F3 53 05   45 23 81 00 C2 36 FC C1  ..&_..S.E#...6..
00E0: 0B B7 45 8B 87 61 F1 21   65 AA F6 34 B4 15 85 AF  ..E..a.!e..4....
00F0: A5 B2 21 C3 65 7E 9D B1   F3 F8 13 8D 58 14 1A F1  ..!.e.......X...
0100: CE 9A 7F 53 6C 6F 96 A3   77 8F 9F                 ...Slo..w..
Thread-7, WRITE: TLSv1.1 Change Cipher Spec, length = 1
[Raw write]: length = 6
0000: 14 03 02 00 01 01                                  ......
*** Finished
verify_data:  { 54, 35, 53, 118, 12, 242, 190, 4, 226, 234, 192, 46 }
***
[write] MD5 and SHA1 hashes:  len = 16
0000: 14 00 00 0C 36 23 35 76   0C F2 BE 04 E2 EA C0 2E  ....6#5v........
Padded plaintext before ENCRYPTION:  len = 64
0000: A9 E5 26 50 4D 1D BE 8B   92 2E 77 12 24 0E DB C5  ..&PM.....w.$...
0010: 14 00 00 0C 36 23 35 76   0C F2 BE 04 E2 EA C0 2E  ....6#5v........
0020: A5 44 16 F6 70 AC 7F 9A   40 CD 5B 4C B9 CD 88 7D  .D..p...@.[L....
0030: 42 78 85 30 0B 0B 0B 0B   0B 0B 0B 0B 0B 0B 0B 0B  Bx.0............
Thread-7, WRITE: TLSv1.1 Handshake, length = 64
[Raw write]: length = 69
0000: 16 03 02 00 40 0C A2 DA   FC 1A 9E CE B0 D6 2F 7B  ....@........./.
0010: 23 9E A9 00 D3 3B FC 2A   C7 DD 5D 22 A6 36 B3 E1  #....;.*..]".6..
0020: CE EB FD 48 C7 55 D3 5B   AF FC 37 3E 49 86 9A 6F  ...H.U.[..7>I..o
0030: 79 A5 FD 5B 60 06 F4 A9   89 CD F4 26 D9 FE F3 9B  y..[`......&....
0040: 78 E0 65 2D 56                                     x.e-V
[Raw read]: length = 5
0000: 15 03 02 00 02                                     .....
[Raw read]: length = 2
0000: 02 2A                                              .*
Thread-7, READ: TLSv1.1 Alert, length = 2
Thread-7, RECV TLSv1.1 ALERT:  fatal, bad_certificate
%% Invalidated:  [Session-1, TLS_RSA_WITH_AES_128_CBC_SHA]
Thread-7, called closeSocket()
Thread-7, handling exception: javax.net.ssl.SSLHandshakeException: Received fatal alert: bad_certificate

      

On the server side, when the client connects, this error is thrown:

[07/Jul/2017:13:33:18] failure (3354): HTTP3068: Error receiving request from 37.222.168.137 (SEC_ERROR_REUSED_ISSUER_AND_SERIAL: Attempting to import a cert which conflicts with issuer/serial of existing cert.)

      

We don't know why it stops working.

  • VB modules also connect to the same server, same url, and it works. I have no VB codes. So I think the card is good.
  • The trust store file in the application includes the issuer ANCERT Certificados para empleados V2

    (sub-root) as well as the root directory ANCERT CGN V2

    (root).

Why is this happening?

EDIT:

In the local trust store, we have the following certificates:

ancert root cert (sha1)
        |
        - ancert sub-root cert (sha1) 

      

And how the chain was built before the problem:

ancert root cert (sha1)
        |
        - ancert sub-root cert (sha1) 
                    |
                    - user cert (sha256)

      

On the server side, the SHA1 root certificate has the same serial number as the SHA256 root certificate.

So I thought it was because when building the chain, Java looks at the chain in the user certificate and wants to find the chain on the server as mentioned in that chain, so it expects intermediate SHA1 and root SHA256, but now when all SHA1 certificates are removed , it can only find SHA256 with the same serial number, so that might be the reason, but I was wrong.

Because we now have another user with this chain , as shown in his public public section :

ancert root cert (sha256)
        |
        - ancert sub-root cert (sha256) 
                    |
                    - user cert (sha256)

      

If my theory is worth it, this user won't complain because SHA256 certificates are always present on the server side, but now he is complaining too.

So what's the reason?

+3


source to share


1 answer


I found the answer: It turns out that after deleting the root CA SHA1 certificate in the IE trusted store, which has the same serial number as SHA256 from the server side, everything started working again. Serial numbers for intermediate CA certificates are not duplicated.

I believe my previous assumptions overlap: when authenticating, creating a user certificate chain, instead of trying to build a chain when the user certificate points , Java seems to look for intermediate and root certs from the Windows system certificate store , i.e. the one we can see with the certmgr

Trusted Intermediate / Root CAs section. And unfortunately, when installing a custom certificate, the installer adds both SHA1 and SHA256 certificates to this store.

And it looks like Java assumes that everything is fine in this store and does not expect a repetition, nor does the serial number; and it sees the SHA1 certificate before seeing the SHA256 root certificate. So, he builds a chain with it and sends it to the server; but on the server side it sees a SHA2 with the same serial number as the conflict.

On the VB side, I think it's because this MS builds the certificate chain in a different way (and with a different ideology: assuming the first chain found is not always the best and sometimes error prone), trying to build all possible chains and finally choose the right one. According to this answer :

If we are talking about Microsoft's implementation (an example I know of) their CCE builds one or more chains (as far as possible) without checking immediately. They just get the certificates and try to follow the ground rules to bind each certificate in the correct place in the chain. When all chains are built, each of them is checked according to the rules described in RFC5280. After verification, there may be a case where multiple trusted and valid chains exist. CCE uses its own selection logic to select only one rung from a set of nets.



So VB code is immune to this kind of errors / repetitions, while Java is more vulnerable at the moment.

Revisiting this issue:

My guess is that the repetition of the serial number is causing attention, forcing users to renew their certificates without being aware of the potential confusion as a result;

And the server administrator must inform us of this change earlier; we received this information a week after the user's report.

Finally, this is further evidence of a long-standing controversy between proactive-reactive programming. I think Java is giving preference to the old one as I ran into another problem related to duplicate alias for different certificates in the same certificate store, where I saw that the way to read Java certificates (by repeating all aliases and getting the first one it sees which looks like here) strongly suggests that Java guys think there shouldn't be duplicate alias in the certificate store. ... This is a known bug, documented here . But I guess it all depends on who your target is, experienced web admins or regular users.

+1


source







All Articles