-
Bug
-
Resolution: Not an Issue
-
P3
-
None
-
1.4.2
-
x86
-
windows_xp
Name: gm110360 Date: 11/19/2003
FULL PRODUCT VERSION :
java version "1.4.1_01"
Java(TM) 2 Runtime Environment, Standard Edition (build 1.4.1_01-b01)
Java HotSpot(TM) Client VM (build 1.4.1_01-b01, mixed mode)
FULL OPERATING SYSTEM VERSION :
Microsoft Windows XP [Version 5.1.2600]
A DESCRIPTION OF THE PROBLEM :
The X509CertSelector.setCertificateValid() method accepts
a Date but does not pass it through to the CertStore
objects. setPrivateKeyValid() works as expected.
STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
1. Build a PKIX cert path builder
2. Call the build() method with a parameter set that
includes an X509CertSelector with setCertificateValid
called.
3. Check the CertSelector passed to the underlying
CertStore instances. The CertificateValid value is always
the current date/time, rather than the date set via
setCertificateValid().
EXPECTED VERSUS ACTUAL BEHAVIOR :
Expected the CertificateValid date passed to the
CertStores to be the date set via setCertificateValid().
Instead, the CertificateValid date passed to the
CertStores is the current date/time.
Using the debug cert store attached below, I see the
following output fragment:
=============================================
DebugCS: getCertificates(X509CertSelector: [
Serial Number: 108445490555297300183856417934260686990
Subject: O=VeriSign\, Inc.,OU=VeriSign Trust
Network,OU=www.verisign.com/repos
itory/RPA Incorp. by Ref.\,LIAB.LTD(c)98,OU=Persona Not
Validated,OU=Digital ID
Class 1 - Microsoft,CN=Robert W.
Shore,1.2.840.113549.1.9.1=#16157277732d3240746
56d706c6172636f72702e636f6d
matchAllSubjectAltNames flag: true
Certificate Valid: Sun Dec 29 08:16:19 EST 2002
Private Key Valid: Wed Jan 01 00:00:00 EST 2003
])
===================================================
Even though both the cert valid and key valid methods get
called with the same Date, only the private-key-valid
value makes it into the selector passed to the CertStore
REPRODUCIBILITY :
This bug can be reproduced always.
---------- BEGIN SOURCE ----------
// The code that builds the various cert store objects is the following.
// You won't be able to run this as-is, since it uses various classes in my
// provider that I'm building to work around the subjectDN comparison problem
// I've reported in previous bugs. However, you should be able to reproduce
// the problem using your own provider with the debug cert store added and
// appropriate changes made to the method below
// ==========================
// Client-side code that attempts to build the chain for a cert.
public void testChain() {
try {
CertificateFactory cf = CertificateFactory.getInstance("X509");
ByteArrayInputStream bis = new ByteArrayInputStream
(RWS_VERISIGN_64.getBytes());
X509Certificate cert = (X509Certificate)cf.generateCertificate
(bis);
CertPathBuilder cpb = CertPathBuilder.getInstance("PKIX");
X509CertSelector certSel = new X509CertSelector();
// It turns out that the Sun Principal implementation builds a
toString()
// that is not acceptable to the Sun CertSelector implementation.
We
// need to set the subject via a byte array, rather than a string.
That's
// what this code does.
X501DistinguishedName dn = X501DistinguishedName.buildInstance
(cert.getSubjectDN());
certSel.setSubject(dn.toAsn().toByteArray());
certSel.setSerialNumber(cert.getSerialNumber());
java.util.Date validDate = (new java.text.SimpleDateFormat
("yyyy/MM/dd")).parse("2003/01/01");
DEBUG("Setting valid date to "+validDate);
certSel.setCertificateValid(validDate);
certSel.setPrivateKeyValid(validDate);
Set trustAnchor = new HashSet();
bis = new ByteArrayInputStream(VERISIGN_CA_64.getBytes());
trustAnchor.add(new TrustAnchor((X509Certificate)
cf.generateCertificate(bis),null));
bis = new ByteArrayInputStream(TEMPLAR_ROOT_64.getBytes());
trustAnchor.add(new TrustAnchor((X509Certificate)
cf.generateCertificate(bis),null));
Set tac = new DebugCollection(trustAnchor);
PKIXBuilderParameters bp = new PKIXBuilderParameters(tac,certSel);
CertStore cs = CertStore.getInstance
("URL",null,"com.templar.crypt");
bp.addCertStore(cs);
Set localSet = new HashSet();
localSet.add(cert);
CollectionCertStoreParameters ccsp = new
CollectionCertStoreParameters(localSet);
// It also turns out that, even with the bytes going in from the
DN, the
// match() method in the CertSelector doesn't find the source
cert. Use
// our own version of the collection cert store
cs = CertStore.getInstance("COLLECTION",ccsp,"com.templar.crypt");
DebugCertStoreParameters dcsp = new DebugCertStoreParameters(cs);
cs = CertStore.getInstance("DEBUG",dcsp);
bp.addCertStore(cs);
CertPathBuilderResult pres = cpb.build(bp);
System.out.println("Result: "+pres);
} catch(Throwable t) {
t.printStackTrace();
throw new RuntimeException(t.getMessage());
}
}
// ==========================================
// Provider-side code
// The critical class is the one used as a debug wrapper around a CertStore
// so I can see just what's being passed. The source for this class is
// the following:
// Parameter class for the debug cert store:
// $Header$
/*
* DebugCertStoreParameters.java
*
* Created on December 26, 2002, 11:04 AM
*/
package com.templar.crypt.provider.cert.test;
import java.security.cert.CertStoreParameters;
import java.security.cert.CertStore;
/**
*
* @author R.W. Shore
*/
public class DebugCertStoreParameters implements CertStoreParameters {
public CertStore realCertStore;
/** Creates a new instance of DebugCertStoreParameters */
public DebugCertStoreParameters(CertStore cs) {
realCertStore = cs;
}
public Object clone() {
return new DebugCertStoreParameters(realCertStore);
}
}
// =================
// Debug cert store itself. Note that this needs to be installed in an
// active security provider to get the debug output reported earlier.
// $Header$
/*
* DebugCertStore.java
*
* Created on December 26, 2002, 10:57 AM
*/
package com.templar.crypt.provider.cert.test;
import java.security.cert.CertStore;
import java.security.cert.CertStoreSpi;
import java.security.cert.CertStoreParameters;
import java.security.InvalidAlgorithmParameterException;
import java.security.cert.CRLSelector;
import java.security.cert.CertStoreException;
import java.security.cert.CertSelector;
/** A wrapper around a real CertStore, so we can debug the method calls.
*
* @author R.W. Shore
*/
public class DebugCertStoreSpi extends java.security.cert.CertStoreSpi {
private CertStore realCertStore;
/** Creates a new instance of DebugCertStore */
public DebugCertStoreSpi(CertStoreParameters p)
throws InvalidAlgorithmParameterException {
super(p);
realCertStore = ((DebugCertStoreParameters)p).realCertStore;
}
public java.util.Collection engineGetCRLs(CRLSelector cRLSelector)
throws CertStoreException {
DEBUG("getCRLs("+cRLSelector+")");
return realCertStore.getCRLs(cRLSelector);
}
public java.util.Collection engineGetCertificates(CertSelector
certSelector)
throws CertStoreException {
DEBUG("getCertificates("+certSelector+")");
return realCertStore.getCertificates(certSelector);
}
private final void DEBUG(Object o) {
System.err.println("DebugCS: "+o);
}
}
// test case by nt126004
import java.util.*
import java.security.*;
import java.text.*;
public class Test {
public static void main(String[] args) {
X509CertSelector certSel = new X509CertSelector();
Date validDate = (new
SimpleDateFormat("yyyy/MM/dd")).parse("2003/01/01");
certSel.setCertificateValid(validDate);
certSel.setPrivateKeyValid(validDate);
System.out.println(certSel);
}
}
---------- END SOURCE ----------
CUSTOMER WORKAROUND :
Requires special CertStore classes
(Incident Review ID: 179474)
======================================================================