JDK-8146592 : X509Factory throws IllegalArgumentException if parsing error occured
  • Type: Bug
  • Component: security-libs
  • Sub-Component: java.security
  • Affected Version: 8u72
  • Priority: P3
  • Status: Resolved
  • Resolution: Duplicate
  • OS: generic
  • CPU: x86_64
  • Submitted: 2015-12-24
  • Updated: 2016-01-12
  • Resolved: 2016-01-12
Related Reports
Duplicate :  
Relates :  
Description
FULL PRODUCT VERSION :


A DESCRIPTION OF THE PROBLEM :
public boolean isX509Certificate(byte[] data)
  {
    try {
      CertificateFactory.getInstance("X.509").generateCertificate(new ByteArrayInputStream(data));
      return true;
    }
    catch (CertificateException e) {      
      return false;
    }
 }

java.lang.IllegalArgumentException: java.lang.IllegalArgumentException: Input byte array has wrong 4-byte ending unit
java.lang.IllegalArgumentException: Input byte array has wrong 4-byte ending unit
	at java.util.Base64$Decoder.decode0(Base64.java:704)
	at java.util.Base64$Decoder.decode(Base64.java:526)
	at java.util.Base64$Decoder.decode(Base64.java:549)
	at sun.security.provider.X509Factory.readOneBlock(X509Factory.java:636)
	at sun.security.provider.X509Factory.engineGenerateCertificate(X509Factory.java:94)
	at java.security.cert.CertificateFactory.generateCertificate(CertificateFactory.java:339)
	at com.kyriba.technical.shared.internal.services.crypto.CryptoTypeDetector.isX509Certificate(CryptoTypeDetector.java:78)

REGRESSION.  Last worked in version 7u79

STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
1. Use the following method
public boolean isX509Certificate(byte[] data)
  {
    try {
      CertificateFactory.getInstance("X.509").generateCertificate(new ByteArrayInputStream(data));
      return true;
    }
    catch (CertificateException e) {      
      return false;
    }
 }

2. Pass non-X509 certificate to this method.

EXPECTED VERSUS ACTUAL BEHAVIOR :
EXPECTED -
generateCertificate throws CertificateException according to javadoc (@exception CertificateException on parsing errors)
ACTUAL -
generateCertificate throws IllegalArgumentException



ERROR MESSAGES/STACK TRACES THAT OCCUR :
java.lang.IllegalArgumentException: java.lang.IllegalArgumentException: Input byte array has wrong 4-byte ending unit
java.lang.IllegalArgumentException: Input byte array has wrong 4-byte ending unit
	at java.util.Base64$Decoder.decode0(Base64.java:704)
	at java.util.Base64$Decoder.decode(Base64.java:526)
	at java.util.Base64$Decoder.decode(Base64.java:549)
	at sun.security.provider.X509Factory.readOneBlock(X509Factory.java:636)
	at sun.security.provider.X509Factory.engineGenerateCertificate(X509Factory.java:94)
	at java.security.cert.CertificateFactory.generateCertificate(CertificateFactory.java:339)
	at com.kyriba.technical.shared.internal.services.crypto.CryptoTypeDetector.isX509Certificate(CryptoTypeDetector.java:78)

REPRODUCIBILITY :
This bug can be reproduced always.

CUSTOMER SUBMITTED WORKAROUND :
public boolean isX509Certificate(byte[] data)
  {
    try {
      CertificateFactory.getInstance("X.509").generateCertificate(new ByteArrayInputStream(data));
      return true;
    }
    catch (CertificateException | IllegalArgumentException e) {      
      return false;
    }
 }


Comments
The issue was solved with backporting JDK-8074935 to jdk8u
12-01-2016

The issue is reproducible using the attached test case on: JDK 7u80 - Pass JDK 8 - Fail JDK 8u66 - Fail JDK 8u72 - Fail JDK 9EA b93 - Pass ----------------------------------------------------------------------------------------------------------------------- Following is the output on JDK 8 and 8u versions: java.lang.IllegalArgumentException: Input byte array has wrong 4-byte ending unit at java.util.Base64$Decoder.decode0(Unknown Source) at java.util.Base64$Decoder.decode(Unknown Source) at java.util.Base64$Decoder.decode(Unknown Source) at sun.security.provider.X509Factory.readOneBlock(Unknown Source) at sun.security.provider.X509Factory.engineGenerateCertificate(Unknown Source) at java.security.cert.CertificateFactory.generateCertificate(Unknown Source) at JI9027825.main(JI9027825.java:26) -------------------------------------------------------------------------------------------------------------------------------------------- Following is the output on JDK 9ea: -------------------------------------------------------------------------------------------------------------------------------------------- D:\Java7Workspace\TestCases\src>java JI9027825 java.security.cert.CertificateException: Could not parse certificate: java.io.IOException: java.lang.IllegalArgumentException: Input byte array has wrong 4-byte ending unit at sun.security.provider.X509Factory.engineGenerateCertificate(X509Factory.java:110) at java.security.cert.CertificateFactory.generateCertificate(CertificateFactory.java:346) at JI9027825.main(JI9027825.java:26) Caused by: java.io.IOException: java.lang.IllegalArgumentException: Input byte array has wrong 4-byte ending unit at sun.security.util.Pem.decode(Pem.java:49) at sun.security.provider.X509Factory.readOneBlock(X509Factory.java:638) at sun.security.provider.X509Factory.engineGenerateCertificate(X509Factory.java:96) ... 2 more Caused by: java.lang.IllegalArgumentException: Input byte array has wrong 4-byte ending unit at java.util.Base64$Decoder.decode0(Base64.java:704) at java.util.Base64$Decoder.decode(Base64.java:526) at sun.security.util.Pem.decode(Pem.java:47) ... 4 more
07-01-2016