Satoru Otsubo
2014-08-18 17:28:26 UTC
I have a question about "BC" provider in cryptography.
In java.security.cert.PKIXParameters, there is a method of setPolicyQualifiersRejected(boolean qualifiersRejected).
In its description of the Oracle documentation (http://docs.oracle.com/javase/7/docs/api/java/security/cert/PKIXParameters.html#setPolicyQualifiersRejected%28boolean%29), there is the following explanation:
Note that the PKIX certification path validation algorithm specifies that any policy qualifier in a certificate policies extension that is marked critical must be processed and validated. Otherwise the certification path must be rejected. If the policyQualifiersRejected flag is set to false, it is up to the application to validate all policy qualifiers in this manner in order to be PKIX compliant.
And in "SUN" provider, if setPolicyQualifiersRejected(true), the cert path validation is rejected when a certificate has a certificatePolicies extension marked critical and when the certificatePolicies extension includes policy qualifiers.
However in "BC" provider, even if setPolicyQualifiersRejected(true), the cert path validation is not rejected. That is, whether or not the argument is true or false, the result is same.
Why is the cert path validation not reejected when the argument of setPolicyQualifiersRejected is true in "BC" provider ?
I attached a sample program below.
-- sample program start ----------------------
import java.io.ByteArrayInputStream;
import java.security.Security;
import java.security.cert.CertificateFactory;
import java.security.cert.CertPath;
import java.security.cert.CertPathValidator;
import java.security.cert.CertPathValidatorException;
import java.security.cert.CertStore;
import java.security.cert.CollectionCertStoreParameters;
import java.security.cert.PolicyNode;
import java.security.cert.PolicyQualifierInfo;
import java.security.cert.PKIXCertPathValidatorResult;
import java.security.cert.PKIXParameters;
import java.security.cert.X509Certificate;
import java.security.cert.TrustAnchor;
import java.util.List;
import java.util.ArrayList;
import java.util.Set;
import java.util.HashSet;
import java.util.Iterator;
import org.bouncycastle.util.encoders.Base64;
import org.bouncycastle.jce.provider.BouncyCastleProvider;
public class PolicyQualifiersRejectedTest{// extends SimpleTest
public static void main(String[] args) throws Exception {
/*
target cert
certificatePolicies critical
policy identifier: 1.2.100.100001.100.100.1
CPS: http://fujicompany.com.jp/repository/
*/
byte[] targetCertByte = Base64.decode(
"MIICzDCCAjWgAwIBAgIBATANBgkqhkiG9w0BAQUFADA0MQswCQYDVQQGEwJKUDEO"
+ "MAwGA1UECBMFVG9reW8xFTATBgNVBAoTDEZ1amkgQ29tcGFueTAeFw0xNDA4MDgw"
+ "OTUzMDRaFw0xNTA4MDgwOTUzMDRaMEkxCzAJBgNVBAYTAkpQMQ4wDAYDVQQIEwVU"
+ "b2t5bzEVMBMGA1UEChMMRnVqaSBDb21wYW55MRMwEQYDVQQDEwptZW1iZXItMTIz"
+ "MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDm5kA8wIZyJSEnSEBxMHwv/L/T"
+ "F3jo1cYV9E7dlQAzuBWNYI/UPbsZkSWhTExRS/j9aicjbymIPaOruH/K65x5FKIp"
+ "RrwXLZUxI/YydlnweNfsoCk/alyD27tuaNb/NLdkZTMVu1JlPQFNlO6GOwOaGlqp"
+ "Vsh/fVJywIER8bmlsQIDAQABo4HYMIHVMAkGA1UdEwQCMAAwTQYDVR0gAQH/BEMw"
+ "QTA/BggqZIaNIWRkATAzMDEGCCsGAQUFBwIBFiVodHRwOi8vZnVqaWNvbXBhbnku"
+ "Y29tLmpwL3JlcG9zaXRvcnkvMAsGA1UdDwQEAwIF4DAsBglghkgBhvhCAQ0EHxYd"
+ "T3BlblNTTCBHZW5lcmF0ZWQgQ2VydGlmaWNhdGUwHQYDVR0OBBYEFBE1NMlZbKGZ"
+ "zKiiVRMreI2IXnBVMB8GA1UdIwQYMBaAFCTMAUWP89gX7bWDx36ttMq9HHCnMA0G"
+ "CSqGSIb3DQEBBQUAA4GBAPdNpUhjpgXAHuGGLoUsp27mSz7hL91qo9ZcU4suH31A"
+ "hqtXjcmVkJ6OpvMylQOmmxtXQ9x6A+Vq9dyyJDshZ74yXsVW4DH2WztCbv+kcRI0"
+ "FZnqOaIfyifLIJdSHfOtlRy/f4YlxVZsqFayF2ngJJ3S6Yipy1gYdfiPXUV+Lf1D");
/*
no intermediate cert
*/
/*
anchor cert
*/
byte[] anchorCertByte = Base64.decode(
"MIICfTCCAeagAwIBAgIJAPJMqRAB8QwZMA0GCSqGSIb3DQEBBQUAMDQxCzAJBgNV"
+ "BAYTAkpQMQ4wDAYDVQQIEwVUb2t5bzEVMBMGA1UEChMMRnVqaSBDb21wYW55MB4X"
+ "DTE0MDgwODA0MzU0NloXDTI0MDgwNTA0MzU0NlowNDELMAkGA1UEBhMCSlAxDjAM"
+ "BgNVBAgTBVRva3lvMRUwEwYDVQQKEwxGdWppIENvbXBhbnkwgZ8wDQYJKoZIhvcN"
+ "AQEBBQADgY0AMIGJAoGBAPuxFKaDGMhEpkv1dQMFCqtjIzFatccDkV6ZI0pZ0Gk+"
+ "bA6mfG45T1kJtO+73/1bu1a3Qq2H7p3KgohZK6s7lsJnPK6lR2wxr6crYi5qX5F7"
+ "r/7AhfWRfY/OoFHO5UEituwp8TVnAXxTAWo0XOOfqAC1Sqkw0XaFBIt55a7+d1mT"
+ "AgMBAAGjgZYwgZMwHQYDVR0OBBYEFCTMAUWP89gX7bWDx36ttMq9HHCnMGQGA1Ud"
+ "IwRdMFuAFCTMAUWP89gX7bWDx36ttMq9HHCnoTikNjA0MQswCQYDVQQGEwJKUDEO"
+ "MAwGA1UECBMFVG9reW8xFTATBgNVBAoTDEZ1amkgQ29tcGFueYIJAPJMqRAB8QwZ"
+ "MAwGA1UdEwQFMAMBAf8wDQYJKoZIhvcNAQEFBQADgYEAgiscsf+aRAj2EocNAxmE"
+ "HqXnDjL5O73L4uDaPtbXXv+r0quNm7mTnuzpilCga/dGF8MVOHET9bQ1nug135P4"
+ "bj3jNDw8HE5mYhd/rgN/ivC9U8qRIsqWfq/2eLQy5iuamvGQ4U6DgM8M1rrYkdFA"
+ "aESVB4X1oVub9UotNNrcZM8=");
Security.addProvider(new BouncyCastleProvider());
CertificateFactory cf = CertificateFactory.getInstance("X.509","BC");
//CertificateFactory cf = CertificateFactory.getInstance("X.509","SUN");
X509Certificate targetCert = (X509Certificate)cf.generateCertificate(
new ByteArrayInputStream(targetCertByte));
X509Certificate anchorCert = (X509Certificate)cf.generateCertificate(
new ByteArrayInputStream(anchorCertByte));
List<X509Certificate> certchain = new ArrayList<X509Certificate>();
certchain.add(targetCert);
CertPath cp = cf.generateCertPath(certchain);
CertPathValidator cpv = CertPathValidator.getInstance("PKIX","BC");
//CertPathValidator cpv = CertPathValidator.getInstance("PKIX","SUN");
Set<TrustAnchor> anchorSet = new HashSet<TrustAnchor>();
TrustAnchor trustAnchr = new TrustAnchor(anchorCert, null);
anchorSet.add(trustAnchr);
PKIXParameters params = new PKIXParameters(anchorSet);
List<X509Certificate> list = new ArrayList<X509Certificate>();
list.add(anchorCert);
list.add(targetCert);
CollectionCertStoreParameters ccsp = new CollectionCertStoreParameters(list);
CertStore store = CertStore.getInstance("Collection", ccsp);
params.addCertStore(store);
params.setRevocationEnabled(false);
params.setPolicyQualifiersRejected(true);
System.out.println("/////////////////////////debug/////////////////////////////");
PKIXCertPathValidatorResult result =
(PKIXCertPathValidatorResult)cpv.validate(cp,params);
System.out.println("/////////////////////////result////////////////////////////");
System.out.println("//--------------anchor cert policy---------------");
PolicyNode anchorPlcyNode = result.getPolicyTree();
System.out.println(
"anchorCert policy identifier: " + anchorPlcyNode.getValidPolicy());
System.out.println("----------------target cert policy---------------");
Iterator<? extends PolicyNode> it = anchorPlcyNode.getChildren();
while(it.hasNext()){
PolicyNode certPathPlcyNode = it.next();
System.out.println(
"targetCert policy identifier: " + certPathPlcyNode.getValidPolicy());
System.out.println(
"targetCert policy critical: " + certPathPlcyNode.isCritical());
Set<? extends java.security.cert.PolicyQualifierInfo> qualifiers =
certPathPlcyNode.getPolicyQualifiers();
System.out.println("targetCert policy qualifiers.size(): " + qualifiers.size());
PolicyQualifierInfo qualifier = qualifiers.iterator().next();
System.out.println(
"targetCert policyQualifierId: " + qualifier.getPolicyQualifierId());
System.out.println(
"targetCert policyQualifier: " + new String(qualifier.getPolicyQualifier()));
}
}
}
/*
Compile:
[path to javac]/javac -cp [path to BC jar]/bcmail-jdk15on-150.jar:[path to BC jar]/bcprov-ext-debug-jdk15on-150.jar:[path to BC jar]/bcpg-jdk15on-150.jar:[path to BC jar]/bcprov-ext-jdk15on-150.jar:[path to BC jar]/bcpkix-jdk15on-150.jar:[path to BC jar]/bcprov-jdk15on-150.jar:[path to BC jar]/bcprov-debug-jdk15on-150.jar:[path to BC jar]/bctest-jdk15on-150.jar:[path to PolicyQualifiersRejectedTest.java] PolicyQualifiersRejectedTest.java
Execution:
[path to java]/java -Djava.security.debug=certpath -cp [path to BC jar]/bcmail-jdk15on-150.jar:[path to BC jar]/bcprov-ext-debug-jdk15on-150.jar:[path to BC jar]/bcpg-jdk15on-150.jar:[path to BC jar]/bcprov-ext-jdk15on-150.jar:[path to BC jar]/bcpkix-jdk15on-150.jar:[path to BC jar]/bcprov-jdk15on-150.jar:[path to BC jar]/bcprov-debug-jdk15on-150.jar:[path to BC jar]/bctest-jdk15on-150.jar:[path to PolicyQualifiersRejectedTest.class] PolicyQualifiersRejectedTest
When you tries the SUN provider, please move // from "SUN" to "BC" in cf and cpv.
*/
-- sample program end -------------------------
Thanks in advance.
Satoru Otsubo
In java.security.cert.PKIXParameters, there is a method of setPolicyQualifiersRejected(boolean qualifiersRejected).
In its description of the Oracle documentation (http://docs.oracle.com/javase/7/docs/api/java/security/cert/PKIXParameters.html#setPolicyQualifiersRejected%28boolean%29), there is the following explanation:
Note that the PKIX certification path validation algorithm specifies that any policy qualifier in a certificate policies extension that is marked critical must be processed and validated. Otherwise the certification path must be rejected. If the policyQualifiersRejected flag is set to false, it is up to the application to validate all policy qualifiers in this manner in order to be PKIX compliant.
And in "SUN" provider, if setPolicyQualifiersRejected(true), the cert path validation is rejected when a certificate has a certificatePolicies extension marked critical and when the certificatePolicies extension includes policy qualifiers.
However in "BC" provider, even if setPolicyQualifiersRejected(true), the cert path validation is not rejected. That is, whether or not the argument is true or false, the result is same.
Why is the cert path validation not reejected when the argument of setPolicyQualifiersRejected is true in "BC" provider ?
I attached a sample program below.
-- sample program start ----------------------
import java.io.ByteArrayInputStream;
import java.security.Security;
import java.security.cert.CertificateFactory;
import java.security.cert.CertPath;
import java.security.cert.CertPathValidator;
import java.security.cert.CertPathValidatorException;
import java.security.cert.CertStore;
import java.security.cert.CollectionCertStoreParameters;
import java.security.cert.PolicyNode;
import java.security.cert.PolicyQualifierInfo;
import java.security.cert.PKIXCertPathValidatorResult;
import java.security.cert.PKIXParameters;
import java.security.cert.X509Certificate;
import java.security.cert.TrustAnchor;
import java.util.List;
import java.util.ArrayList;
import java.util.Set;
import java.util.HashSet;
import java.util.Iterator;
import org.bouncycastle.util.encoders.Base64;
import org.bouncycastle.jce.provider.BouncyCastleProvider;
public class PolicyQualifiersRejectedTest{// extends SimpleTest
public static void main(String[] args) throws Exception {
/*
target cert
certificatePolicies critical
policy identifier: 1.2.100.100001.100.100.1
CPS: http://fujicompany.com.jp/repository/
*/
byte[] targetCertByte = Base64.decode(
"MIICzDCCAjWgAwIBAgIBATANBgkqhkiG9w0BAQUFADA0MQswCQYDVQQGEwJKUDEO"
+ "MAwGA1UECBMFVG9reW8xFTATBgNVBAoTDEZ1amkgQ29tcGFueTAeFw0xNDA4MDgw"
+ "OTUzMDRaFw0xNTA4MDgwOTUzMDRaMEkxCzAJBgNVBAYTAkpQMQ4wDAYDVQQIEwVU"
+ "b2t5bzEVMBMGA1UEChMMRnVqaSBDb21wYW55MRMwEQYDVQQDEwptZW1iZXItMTIz"
+ "MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDm5kA8wIZyJSEnSEBxMHwv/L/T"
+ "F3jo1cYV9E7dlQAzuBWNYI/UPbsZkSWhTExRS/j9aicjbymIPaOruH/K65x5FKIp"
+ "RrwXLZUxI/YydlnweNfsoCk/alyD27tuaNb/NLdkZTMVu1JlPQFNlO6GOwOaGlqp"
+ "Vsh/fVJywIER8bmlsQIDAQABo4HYMIHVMAkGA1UdEwQCMAAwTQYDVR0gAQH/BEMw"
+ "QTA/BggqZIaNIWRkATAzMDEGCCsGAQUFBwIBFiVodHRwOi8vZnVqaWNvbXBhbnku"
+ "Y29tLmpwL3JlcG9zaXRvcnkvMAsGA1UdDwQEAwIF4DAsBglghkgBhvhCAQ0EHxYd"
+ "T3BlblNTTCBHZW5lcmF0ZWQgQ2VydGlmaWNhdGUwHQYDVR0OBBYEFBE1NMlZbKGZ"
+ "zKiiVRMreI2IXnBVMB8GA1UdIwQYMBaAFCTMAUWP89gX7bWDx36ttMq9HHCnMA0G"
+ "CSqGSIb3DQEBBQUAA4GBAPdNpUhjpgXAHuGGLoUsp27mSz7hL91qo9ZcU4suH31A"
+ "hqtXjcmVkJ6OpvMylQOmmxtXQ9x6A+Vq9dyyJDshZ74yXsVW4DH2WztCbv+kcRI0"
+ "FZnqOaIfyifLIJdSHfOtlRy/f4YlxVZsqFayF2ngJJ3S6Yipy1gYdfiPXUV+Lf1D");
/*
no intermediate cert
*/
/*
anchor cert
*/
byte[] anchorCertByte = Base64.decode(
"MIICfTCCAeagAwIBAgIJAPJMqRAB8QwZMA0GCSqGSIb3DQEBBQUAMDQxCzAJBgNV"
+ "BAYTAkpQMQ4wDAYDVQQIEwVUb2t5bzEVMBMGA1UEChMMRnVqaSBDb21wYW55MB4X"
+ "DTE0MDgwODA0MzU0NloXDTI0MDgwNTA0MzU0NlowNDELMAkGA1UEBhMCSlAxDjAM"
+ "BgNVBAgTBVRva3lvMRUwEwYDVQQKEwxGdWppIENvbXBhbnkwgZ8wDQYJKoZIhvcN"
+ "AQEBBQADgY0AMIGJAoGBAPuxFKaDGMhEpkv1dQMFCqtjIzFatccDkV6ZI0pZ0Gk+"
+ "bA6mfG45T1kJtO+73/1bu1a3Qq2H7p3KgohZK6s7lsJnPK6lR2wxr6crYi5qX5F7"
+ "r/7AhfWRfY/OoFHO5UEituwp8TVnAXxTAWo0XOOfqAC1Sqkw0XaFBIt55a7+d1mT"
+ "AgMBAAGjgZYwgZMwHQYDVR0OBBYEFCTMAUWP89gX7bWDx36ttMq9HHCnMGQGA1Ud"
+ "IwRdMFuAFCTMAUWP89gX7bWDx36ttMq9HHCnoTikNjA0MQswCQYDVQQGEwJKUDEO"
+ "MAwGA1UECBMFVG9reW8xFTATBgNVBAoTDEZ1amkgQ29tcGFueYIJAPJMqRAB8QwZ"
+ "MAwGA1UdEwQFMAMBAf8wDQYJKoZIhvcNAQEFBQADgYEAgiscsf+aRAj2EocNAxmE"
+ "HqXnDjL5O73L4uDaPtbXXv+r0quNm7mTnuzpilCga/dGF8MVOHET9bQ1nug135P4"
+ "bj3jNDw8HE5mYhd/rgN/ivC9U8qRIsqWfq/2eLQy5iuamvGQ4U6DgM8M1rrYkdFA"
+ "aESVB4X1oVub9UotNNrcZM8=");
Security.addProvider(new BouncyCastleProvider());
CertificateFactory cf = CertificateFactory.getInstance("X.509","BC");
//CertificateFactory cf = CertificateFactory.getInstance("X.509","SUN");
X509Certificate targetCert = (X509Certificate)cf.generateCertificate(
new ByteArrayInputStream(targetCertByte));
X509Certificate anchorCert = (X509Certificate)cf.generateCertificate(
new ByteArrayInputStream(anchorCertByte));
List<X509Certificate> certchain = new ArrayList<X509Certificate>();
certchain.add(targetCert);
CertPath cp = cf.generateCertPath(certchain);
CertPathValidator cpv = CertPathValidator.getInstance("PKIX","BC");
//CertPathValidator cpv = CertPathValidator.getInstance("PKIX","SUN");
Set<TrustAnchor> anchorSet = new HashSet<TrustAnchor>();
TrustAnchor trustAnchr = new TrustAnchor(anchorCert, null);
anchorSet.add(trustAnchr);
PKIXParameters params = new PKIXParameters(anchorSet);
List<X509Certificate> list = new ArrayList<X509Certificate>();
list.add(anchorCert);
list.add(targetCert);
CollectionCertStoreParameters ccsp = new CollectionCertStoreParameters(list);
CertStore store = CertStore.getInstance("Collection", ccsp);
params.addCertStore(store);
params.setRevocationEnabled(false);
params.setPolicyQualifiersRejected(true);
System.out.println("/////////////////////////debug/////////////////////////////");
PKIXCertPathValidatorResult result =
(PKIXCertPathValidatorResult)cpv.validate(cp,params);
System.out.println("/////////////////////////result////////////////////////////");
System.out.println("//--------------anchor cert policy---------------");
PolicyNode anchorPlcyNode = result.getPolicyTree();
System.out.println(
"anchorCert policy identifier: " + anchorPlcyNode.getValidPolicy());
System.out.println("----------------target cert policy---------------");
Iterator<? extends PolicyNode> it = anchorPlcyNode.getChildren();
while(it.hasNext()){
PolicyNode certPathPlcyNode = it.next();
System.out.println(
"targetCert policy identifier: " + certPathPlcyNode.getValidPolicy());
System.out.println(
"targetCert policy critical: " + certPathPlcyNode.isCritical());
Set<? extends java.security.cert.PolicyQualifierInfo> qualifiers =
certPathPlcyNode.getPolicyQualifiers();
System.out.println("targetCert policy qualifiers.size(): " + qualifiers.size());
PolicyQualifierInfo qualifier = qualifiers.iterator().next();
System.out.println(
"targetCert policyQualifierId: " + qualifier.getPolicyQualifierId());
System.out.println(
"targetCert policyQualifier: " + new String(qualifier.getPolicyQualifier()));
}
}
}
/*
Compile:
[path to javac]/javac -cp [path to BC jar]/bcmail-jdk15on-150.jar:[path to BC jar]/bcprov-ext-debug-jdk15on-150.jar:[path to BC jar]/bcpg-jdk15on-150.jar:[path to BC jar]/bcprov-ext-jdk15on-150.jar:[path to BC jar]/bcpkix-jdk15on-150.jar:[path to BC jar]/bcprov-jdk15on-150.jar:[path to BC jar]/bcprov-debug-jdk15on-150.jar:[path to BC jar]/bctest-jdk15on-150.jar:[path to PolicyQualifiersRejectedTest.java] PolicyQualifiersRejectedTest.java
Execution:
[path to java]/java -Djava.security.debug=certpath -cp [path to BC jar]/bcmail-jdk15on-150.jar:[path to BC jar]/bcprov-ext-debug-jdk15on-150.jar:[path to BC jar]/bcpg-jdk15on-150.jar:[path to BC jar]/bcprov-ext-jdk15on-150.jar:[path to BC jar]/bcpkix-jdk15on-150.jar:[path to BC jar]/bcprov-jdk15on-150.jar:[path to BC jar]/bcprov-debug-jdk15on-150.jar:[path to BC jar]/bctest-jdk15on-150.jar:[path to PolicyQualifiersRejectedTest.class] PolicyQualifiersRejectedTest
When you tries the SUN provider, please move // from "SUN" to "BC" in cf and cpv.
*/
-- sample program end -------------------------
Thanks in advance.
Satoru Otsubo