JDK-6209956 : REGRESSION: getExtensionValue() sometimes incorrectly returns null in v1.5
  • Type: Bug
  • Component: security-libs
  • Sub-Component: java.security
  • Affected Version: 5.0
  • Priority: P3
  • Status: Resolved
  • Resolution: Fixed
  • OS: windows_2000
  • CPU: x86
  • Submitted: 2004-12-17
  • Updated: 2010-04-02
  • Resolved: 2005-10-08
The Version table provides details related to the release that this issue/RFE will be addressed.

Unresolved : Release in which this issue/RFE will be addressed.
Resolved: Release in which this issue/RFE has been resolved.
Fixed : Release in which this issue/RFE has been fixed. The release containing this fix may be available for download as an Early Access Release or a General Availability Release.

To download the current JDK release, click here.
Other JDK 6
5.0u7Fixed 6 betaFixed
Description
FULL PRODUCT VERSION :
java version "1.5.0"
Java(TM) 2 Runtime Environment, Standard Edition (build 1.5.0-b64)
Java HotSpot(TM) Client VM (build 1.5.0-b64, mixed mode, sharing)

ADDITIONAL OS VERSION INFORMATION :
Microsoft Windows 2000 [Version 5.00.2195]

A DESCRIPTION OF THE PROBLEM :
When the CDP extension (2.5.29.31) hast LDAP name with no default host the parsing fails.

The LDAP entry is in the format of:
ldap:///CN=XXX,OU=YYY,C=XX

This should work.

The sun.security.util.URIName class expects to have a host name, and in this case it failed with "URI name must include host" error.

I've read the sepc and found no imply to force the user to specify the LDAP server.

This issue is new to J2SE 1.5

STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :

Have a certificate with CDP entry of ldap:///xxxxxx
Try to parse the certificate.

EXPECTED VERSUS ACTUAL BEHAVIOR :
EXPECTED -
CDP entry of ldap:///xxxxx be accepted.

NOTICE!!!
Even if the OCTET-STRING fails, the cert.getExtensionValue should return the byte array and not null.

Currently, if Java class cannot parse the OCTET-STRING a null is returned, this is incorrect behavior, since the extension exists.
ACTUAL -
When CDP entry of ldap:///xxxxx is specified in certificate the cert.getExtensionValue ("2.5.29.31") returns null.

ERROR MESSAGES/STACK TRACES THAT OCCUR :
Unparseable certificate extensions: 1
[1]: ObjectId: 2.5.29.31 Criticality=false

REPRODUCIBILITY :
This bug can be reproduced always.

---------- BEGIN SOURCE ----------

import java.io.*;
import java.lang.*;
import java.security.cert.*;
import javax.security.auth.x500.*;

public class cert
{
	static public void main (String args[]) {
		try {
			if (args.length != 1) {
				throw new Exception ("Usage: cert pem_cert_file");
			}

			InputStream inStream = new FileInputStream (args[0]);
			CertificateFactory cf = CertificateFactory.getInstance ("X.509");
			X509Certificate cert = (X509Certificate)cf.generateCertificate (inStream);
			inStream.close ();

			System.out.println ("Issuer:\t" + cert.getIssuerX500Principal().getName (X500Principal.RFC2253));
			System.out.println ("Subject:\t" + cert.getSubjectX500Principal().getName (X500Principal.RFC2253));
			System.out.println ("Serial:\t\t" + cert.getSerialNumber ().toString (16));
			System.out.println ("NotBefore:\t" + cert.getNotBefore());
			System.out.println ("NotAfter:\t" + cert.getNotAfter());
			System.out.println ("CDP:\t" + cert.getExtensionValue ("2.5.29.31"));
		}
		catch (CertificateException e) {
			System.out.println ("CertificateException:" + e.toString ());
		}
		catch (IOException e) {
			System.out.println ("IOException: " + e.toString ());
		}
		catch (Exception e) {
			System.out.println ("Exception: " + e.toString ());
		}
	}
}

Use the following certificate:
-----BEGIN CERTIFICATE-----
MIIH2jCCBcKgAwIBAgIKYVqdYwAAAAAAAzANBgkqhkiG9w0BAQUFADBDMQswCQYD
VQQGEwJJTDEMMAoGA1UEChMDWG9yMQ0wCwYDVQQLEwRUZXN0MRcwFQYDVQQDEw5Y
MU5FVDQgUm9vdCBDQTAeFw0wNDA1MDYxMzI2MzlaFw0wNTA1MDYxMzI2MzlaMEsx
CzAJBgNVBAYTAklMMQwwCgYDVQQKEwNYb3IxDTALBgNVBAsTBFRlc3QxHzAdBgNV
BAMTFlgxTkVUNCBBdWRpdCBTaWduYXR1cmUwggEiMA0GCSqGSIb3DQEBAQUAA4IB
DwAwggEKAoIBAQCZo5CGKeHaBAB+b2Fyz7fVgSpgbKS8r+CYO1Y2SZxhPfHRXVwH
P1+r6EfCct5pt6ElN8EPHGdNyH6BvwA2F4sE3m4I9JTX9DfTRAz6uPvySlC1ZPbh
nXmX0aHIMUG5RUVAZsNA6nRZy8aK+IVPrZl6IkeDU7cx4g99QMy/RADzMcl5aubj
5oO9Yfl24p/7IYNJElPcCrCLu8YnnsD3zFrKoBLpUqT/Tq9qf7J0LGbeCdIUvBmx
vTfm5zs8d5wJyT9W09LYT9rPyDrwh2xX974MTXi4Ee3bUdLq8/e4KnXxm08j1v+P
Lx/bhViX8k3hxW2iIfXQGKxXBUw2wIWJQ1OZAgMBAAGjggPGMIIDwjALBgNVHQ8E
BAMCB4AwHQYDVR0OBBYEFJP0VIsjOPaGm2kQUxM7fKCax6spMD0GCSsGAQQBgjcV
BwQwMC4GJisGAQQBgjcVCISRy1GExIEYguWPL4TL5iiDmpApf4W2qGWBvdxUAgFk
AgEDMB8GA1UdIwQYMBaAFMvFaJP/rSuk6J/dERLxibj1mUlKMIIBCwYDVR0fBIIB
AjCB/zCB/KCB+aCB9oaBt2xkYXA6Ly8vQ049WDFORVQ0JTIwUm9vdCUyMENBLENO
PXgxbmV0NCxDTj1DRFAsQ049UHVibGljJTIwS2V5JTIwU2VydmljZXMsQ049U2Vy
dmljZXMsQ049Q29uZmlndXJhdGlvbixEQz10ZXN0LERDPWxvY2FsP2NlcnRpZmlj
YXRlUmV2b2NhdGlvbkxpc3Q/YmFzZT9vYmplY3RDbGFzcz1jUkxEaXN0cmlidXRp
b25Qb2ludIY6aHR0cDovL3gxbmV0NC50ZXN0LmxvY2FsL0NlcnRFbnJvbGwvWDFO
RVQ0JTIwUm9vdCUyMENBLmNybDCCAR8GCCsGAQUFBwEBBIIBETCCAQ0wgbAGCCsG
AQUFBzAChoGjbGRhcDovLy9DTj1YMU5FVDQlMjBSb290JTIwQ0EsQ049QUlBLENO
PVB1YmxpYyUyMEtleSUyMFNlcnZpY2VzLENOPVNlcnZpY2VzLENOPUNvbmZpZ3Vy
YXRpb24sREM9dGVzdCxEQz1sb2NhbD9jQUNlcnRpZmljYXRlP2Jhc2U/b2JqZWN0
Q2xhc3M9Y2VydGlmaWNhdGlvbkF1dGhvcml0eTBYBggrBgEFBQcwAoZMaHR0cDov
L3gxbmV0NC50ZXN0LmxvY2FsL0NlcnRFbnJvbGwveDFuZXQ0LnRlc3QubG9jYWxf
WDFORVQ0JTIwUm9vdCUyMENBLmNydDAxBgNVHSUEKjAoBiYrBgEEAYI3FQiEkctR
hMSBGILljy+Ey+Yog5qQKX+B2fsxhcyoRTCBkwYDVR0gBIGLMIGIMIGFBiUrBgEE
AYI3FQiEkctRhMSBGILljy+Ey+Yog5qQKX+/4BSHuqQvMFwwWgYIKwYBBQUHAgEe
TgBoAHQAdABwADoALwAvAGwAbwBjAGEAbABoAG8AcwB0AC8AWABDAGUAcgB0AFgA
dABlAG4AZABlAHIALwBJAHMAcwB1AGEAbgBjAGUAMTA5BgkrBgEEAYI3FQoELDAq
MCgGJisGAQQBgjcVCISRy1GExIEYguWPL4TL5iiDmpApf4HZ+zGFzKhFMA0GCSqG
SIb3DQEBBQUAA4ICAQBy92QsfdCG8Es0hc+hEI7SADjqD/s76U3/BacAY0cwUNdD
RezHGdL6nrmEj7iN1b+4P8VQBmlJGWcf/SsKj4/RPnzRgcfIcO/ULSJUXtciSygb
1LH8e8glPFAEAhQs9l0nyvBhqI+Mc23HXTGg+bk2Ip2+VjjmzwuhWYSaTiT7LGjP
3oyd9uLdlqVyudTL6P+oox6ffh6TPRV4EvxxLWrd1KYEXgY4OhLWClI73ZHk1JKR
sVVSJWoqeN2TNyOGS86A7FAMU52Il9qJB4sETfiT4IsuHT7rVF76mVQK+MwIiyS6
vRKDwhyUmIByXSz2RspXnzaYRModtwamDFa68P4xgJOY5ijaNV3tB3D7ZMnf7Wb3
oxS0JKkq2GrKR5Bhr2u2ZYJ8fkYHE0a9wYwXeq0c8rkxvyiU2vgP6dLP1aUc79Ft
ajw/icA+fZevCrmCSahCuf485VHR/LM5Nfkg5lRS7BsWcWB7SrGlQsYyIylqpnG/
mXS4D3l1v5tdnoVoVQ37y31LUIfLQL7Qzy3YclHWo1ZTi9m1W26fNaRupYrjTQN6
1/9eNKaeLIj+P0H9Io8m7+A4xNhj4eM638yEAslL+g9VMcBbCFVshe2IVng4Ka/d
OhsLLlE7EEKF1p+lSJFLL5US1Fn38BznCOjijPjNIKkvxRi9bVMULk04jYF/iw==
-----END CERTIFICATE-----

---------- END SOURCE ----------

Release Regression From : 4.2
The above release value was the last known release where this 
bug was known to work. Since then there has been a regression.
###@###.### 2004-12-17 08:45:21 GMT
FULL PRODUCT VERSION :
java version "1.5.0_01"
Java(TM) 2 Runtime Environment, Standard Edition (build 1.5.0_01-b08)
Java HotSpot(TM) Client VM (build 1.5.0_01-b08, mixed mode, sharing)

ADDITIONAL OS VERSION INFORMATION :
Microsoft Windows 2000 [Version 5.00.2195]

A DESCRIPTION OF THE PROBLEM :
Java 1.5 has problems decoding an X509Certificate via the CertificateFactory class. Though CertificateFactory.getInstance("X509").generateCertificate(...) works without error, X509Certificate.getExtensionValue(...) return null for Extension OIDs, that are definitely there. Also, X509Certicicate.getEncoded() returns wrong data, that cant be used to reproduce an X509Certificate via the CertificateFactory. It looks, as if the physically last certificate extension is affected. Thus, it looks like beeing a problem of the length calculation of the underlying DER encoding. This problem does not occur in Java 1.3 and Java 1.4, but is reproducable in 1.6 (Mustang)

STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
Try the following code snippet to read the CRLDistributionPoint extension from a certificate:

try{
  CertificateFactory lCertFact = CertificateFactory.getInstance("X509");
  X509Certificate lCert = (X509Certificate) lCertFact.generateCertificate(new FileInputStream("D:\\Sorglos.cer"));
  System.out.println(lCert.getSubjectDN().getName());
  // extension 2.5.29.31 is crldistribution point, the below call returns null
  // and thus gives an exception, though the extension is present
  System.out.println(lCert.getExtensionValue("2.5.29.31").length);
} catch (Exception e) {e.printStackTrace();}

Here the certificate to reproduce in base 64:

-----BEGIN CERTIFICATE-----
MIIDoTCCAwqgAwIBAgICYeUwDQYJKoZIhvcNAQEFBQAwPjELMAkGA1UEBhMCREUx
FTATBgNVBAoTDEQtVHJ1c3QgR21iSDEYMBYGA1UEAxMPRC1UUlVTVCBUZXN0IENB
MB4XDTA1MDMwODExMTAyMVoXDTA2MDMwODExMTAyMVowgbAxCzAJBgNVBAYTAkRF
MRYwFAYDVQQKEw1HbGFza2xhciBHbWJIMRYwFAYDVQQLEw0zMTAwMDIyNTU3ODk5
MRUwEwYDVQQDEwxSdWRpIFNvcmdsb3MxDTALBgNVBCoTBFJ1ZGkxEDAOBgNVBAQT
B1Nvcmdsb3MxHTAbBgNVBAUTFERUUjAxMDAwMDAwMDAwMDFURVNUMRowGAYDVQQH
ExFJSEsgSGludGVydHVwZmluZzCBnzANBgkqhkiG9w0BAQEFAAOBjQAwgYkCgYEA
5CjRZ0zUudgN0XePrhBG97xkManLqbooTfM55SRoWW3JXEyEvxQlLCkUP9AEcmPR
Y7iD8wi53OG/zS5EhkHgEiJxNn2FGta8/Oj3CtZHW/qOZqT9sFGMhxVY43qJZmuq
GPE/JlkYfjxUP5xcjQrIZTkYyHnDceSclbO4oe28DZkCAwDX56OCATkwggE1MBEG
A1UdDgQKBAhD6Nouoi+GYDAXBgNVHSAEEDAOMAwGCisGAQQBpTQCFAEwIwYDVR0R
BBwwGoEYcnVkaS5zb3JnbG9zQGdsYXNrbGFyLmRlMFAGA1UdIwRJMEehQqRAMD4x
CzAJBgNVBAYTAkRFMRUwEwYDVQQKEwxELVRydXN0IEdtYkgxGDAWBgNVBAMTD0Qt
VFJVU1QgVGVzdCBDQYIBUDAwBggrBgEFBQcBAQQkMCIwIAYIKwYBBQUHMAGGFG9j
c3AuZC10cnVzdC5kZTo5MDAwMA4GA1UdDwEB/wQEAwIGQDBOBgNVHR8ERzBFMEOg
QaA/hj1sZGFwOi8vZGlyZWN0b3J5LmQtdHJ1c3QuZGUvQ049RC1UUlVTVC1DQSxP
PUQtVHJ1c3QgR21iSCxDPURFMA0GCSqGSIb3DQEBBQUAA4GBAAWbxKZ/J3nWSB8J
9pSuWOdxNjsL32UkqNmU0aR47jjXX5dYtrxEbTVIWSHnhv7PiQEFd/LeEiYp72F4
z7u/54V2Cxcqio+QQ5SSDmEYsNEeIc7l20nEmFbfZlzeL6lbOZ7j6WJSUqCI3T7A
/yI1WRoPGXMvhX2w2S/cs8AACR00
-----END CERTIFICATE-----

Convert it to binary and save it as Sorglos.cer


EXPECTED VERSUS ACTUAL BEHAVIOR :
EXPECTED -
The length of the crl distribution point extension should be 73 bytes as returned by Java 1.3 and 1.4
ACTUAL -
getExtensionValue() returns null and thus the code snippet ends with a null pointer exception in Java 1.5

ERROR MESSAGES/STACK TRACES THAT OCCUR :
L=IHK Hintertupfing, SERIALNUMBER=DTR0100000000001TEST, SURNAME=Sorglos, GIVENNAME=Rudi, CN=Rudi Sorglos, OU=3100022557899, O=Glasklar GmbH, C=DE
java.lang.NullPointerException
        at Test.main(Test.java)

REPRODUCIBILITY :
This bug can be reproduced always.

Comments
EVALUATION The problem is that in our X509Certificate implementation getExtensionValue() does not examine extensions that are known but could not be parsed due to errors. Parsing and handling of ldap:///... URIs is a separate issue and tracked by 5107944. ###@###.### 2004-12-20 22:46:40 GMT
20-12-2004