11/*
2- * Copyright (c) 2013, 2021 , Oracle and/or its affiliates. All rights reserved.
2+ * Copyright (c) 2013, 2026 , Oracle and/or its affiliates. All rights reserved.
33 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
44 *
55 * This code is free software; you can redistribute it and/or modify it
2828import java .io .IOException ;
2929import java .math .BigInteger ;
3030import java .security .MessageDigest ;
31- import java .security .PublicKey ;
3231import java .security .cert .Certificate ;
3332import java .security .cert .CertificateFactory ;
3433import java .security .cert .X509Certificate ;
35- import java .security .interfaces .ECPublicKey ;
3634import java .util .ArrayList ;
3735import java .util .Arrays ;
3836import java .util .Collection ;
3937import java .util .List ;
4038import java .util .Set ;
4139import java .util .TreeSet ;
4240
41+ import sun .security .util .CurveDB ;
4342import sun .security .util .DerInputStream ;
4443import sun .security .util .DerOutputStream ;
4544import sun .security .util .DerValue ;
@@ -140,11 +139,8 @@ private static List<byte[]> altEncodings(X509Certificate c)
140139 List <DerValue > algIds = Arrays .asList (seq [1 ], altAlgId (seq [1 ]));
141140
142141 List <DerValue > sigs ;
143- PublicKey p = c .getPublicKey ();
144- if (p instanceof ECPublicKey ) {
145- ECPublicKey ep = (ECPublicKey ) p ;
146- BigInteger mod = ep .getParams ().getOrder ();
147- sigs = Arrays .asList (seq [2 ], altSig (mod , seq [2 ]));
142+ if (c .getSigAlgName ().contains ("ECDSA" )) {
143+ sigs = Arrays .asList (seq [2 ], altSig (seq [2 ]));
148144 } else {
149145 sigs = Arrays .asList (seq [2 ]);
150146 }
@@ -163,14 +159,27 @@ private static List<byte[]> altEncodings(X509Certificate c)
163159 return result ;
164160 }
165161
166- private static DerValue altSig (BigInteger mod , DerValue sig )
162+ private static DerValue altSig (DerValue sig )
167163 throws IOException {
168164 byte [] sigBits = sig .getBitString ();
165+ int sigLength = sigBits .length ;
169166 DerInputStream in =
170- new DerInputStream (sigBits , 0 , sigBits . length , false );
167+ new DerInputStream (sigBits , 0 , sigLength , false );
171168 DerValue [] values = in .getSequence (2 );
172169 BigInteger r = values [0 ].getBigInteger ();
173170 BigInteger s = values [1 ].getBigInteger ();
171+ BigInteger mod ;
172+ // The following checks cover more than 99.99999% of signature lengths
173+ // for the three NIST-P curves. Fail if the length lies outside.
174+ if (sigLength >= 100 && sigLength <= 104 ) {
175+ mod = CurveDB .P_384 .getOrder ();
176+ } else if (sigLength >= 68 && sigLength <= 72 ) {
177+ mod = CurveDB .P_256 .getOrder ();
178+ } else if (sigLength >= 135 && sigLength <= 139 ) {
179+ mod = CurveDB .P_521 .getOrder ();
180+ } else {
181+ throw new RuntimeException ("Unrecognized signature length: " + sigLength );
182+ }
174183 BigInteger s2 = s .negate ().mod (mod );
175184 DerOutputStream out = new DerOutputStream ();
176185 out .putInteger (r );
0 commit comments