mirror of
https://github.com/openjdk/jdk.git
synced 2025-08-26 14:24:46 +02:00
8346094: Harden X509CertImpl.getExtensionValue for NPE cases
Reviewed-by: coffeys, weijun
This commit is contained in:
parent
efbad00c4d
commit
70a6c0b7ac
3 changed files with 220 additions and 57 deletions
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 1996, 2023, Oracle and/or its affiliates. All rights reserved.
|
* Copyright (c) 1996, 2025, Oracle and/or its affiliates. All rights reserved.
|
||||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||||
*
|
*
|
||||||
* This code is free software; you can redistribute it and/or modify it
|
* This code is free software; you can redistribute it and/or modify it
|
||||||
|
@ -120,7 +120,7 @@ public class X509CertImpl extends X509Certificate implements DerEncoder {
|
||||||
*/
|
*/
|
||||||
public X509CertImpl(X509CertInfo info, AlgorithmId algId, byte[] signature,
|
public X509CertImpl(X509CertInfo info, AlgorithmId algId, byte[] signature,
|
||||||
byte[] signedCert) {
|
byte[] signedCert) {
|
||||||
this.info = info;
|
this.info = Objects.requireNonNull(info);
|
||||||
this.algId = algId;
|
this.algId = algId;
|
||||||
this.signature = signature;
|
this.signature = signature;
|
||||||
this.signedCert = Objects.requireNonNull(signedCert);
|
this.signedCert = Objects.requireNonNull(signedCert);
|
||||||
|
@ -553,7 +553,7 @@ public class X509CertImpl extends X509Certificate implements DerEncoder {
|
||||||
* before this function may be called.
|
* before this function may be called.
|
||||||
*/
|
*/
|
||||||
public String toString() {
|
public String toString() {
|
||||||
if (info == null || algId == null || signature == null)
|
if (algId == null || signature == null)
|
||||||
return "";
|
return "";
|
||||||
|
|
||||||
HexDumpEncoder encoder = new HexDumpEncoder();
|
HexDumpEncoder encoder = new HexDumpEncoder();
|
||||||
|
@ -570,8 +570,6 @@ public class X509CertImpl extends X509Certificate implements DerEncoder {
|
||||||
* @return the publickey.
|
* @return the publickey.
|
||||||
*/
|
*/
|
||||||
public PublicKey getPublicKey() {
|
public PublicKey getPublicKey() {
|
||||||
if (info == null)
|
|
||||||
return null;
|
|
||||||
return info.getKey().getKey();
|
return info.getKey().getKey();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -581,8 +579,6 @@ public class X509CertImpl extends X509Certificate implements DerEncoder {
|
||||||
* @return the version number, i.e. 1, 2 or 3.
|
* @return the version number, i.e. 1, 2 or 3.
|
||||||
*/
|
*/
|
||||||
public int getVersion() {
|
public int getVersion() {
|
||||||
if (info == null)
|
|
||||||
return -1;
|
|
||||||
try {
|
try {
|
||||||
int vers = info.getVersion().getVersion();
|
int vers = info.getVersion().getVersion();
|
||||||
return vers + 1;
|
return vers + 1;
|
||||||
|
@ -609,8 +605,6 @@ public class X509CertImpl extends X509Certificate implements DerEncoder {
|
||||||
* @return the serial number.
|
* @return the serial number.
|
||||||
*/
|
*/
|
||||||
public SerialNumber getSerialNumberObject() {
|
public SerialNumber getSerialNumberObject() {
|
||||||
if (info == null)
|
|
||||||
return null;
|
|
||||||
return info.getSerialNumber().getSerial();
|
return info.getSerialNumber().getSerial();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -622,8 +616,6 @@ public class X509CertImpl extends X509Certificate implements DerEncoder {
|
||||||
*/
|
*/
|
||||||
@SuppressWarnings("deprecation")
|
@SuppressWarnings("deprecation")
|
||||||
public Principal getSubjectDN() {
|
public Principal getSubjectDN() {
|
||||||
if (info == null)
|
|
||||||
return null;
|
|
||||||
return info.getSubject();
|
return info.getSubject();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -633,9 +625,6 @@ public class X509CertImpl extends X509Certificate implements DerEncoder {
|
||||||
* also aware of X509CertImpl mutability.
|
* also aware of X509CertImpl mutability.
|
||||||
*/
|
*/
|
||||||
public X500Principal getSubjectX500Principal() {
|
public X500Principal getSubjectX500Principal() {
|
||||||
if (info == null) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
try {
|
try {
|
||||||
return info.getSubject().asX500Principal();
|
return info.getSubject().asX500Principal();
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
|
@ -650,8 +639,6 @@ public class X509CertImpl extends X509Certificate implements DerEncoder {
|
||||||
*/
|
*/
|
||||||
@SuppressWarnings("deprecation")
|
@SuppressWarnings("deprecation")
|
||||||
public Principal getIssuerDN() {
|
public Principal getIssuerDN() {
|
||||||
if (info == null)
|
|
||||||
return null;
|
|
||||||
return info.getIssuer();
|
return info.getIssuer();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -661,9 +648,6 @@ public class X509CertImpl extends X509Certificate implements DerEncoder {
|
||||||
* also aware of X509CertImpl mutability.
|
* also aware of X509CertImpl mutability.
|
||||||
*/
|
*/
|
||||||
public X500Principal getIssuerX500Principal() {
|
public X500Principal getIssuerX500Principal() {
|
||||||
if (info == null) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
try {
|
try {
|
||||||
return info.getIssuer().asX500Principal();
|
return info.getIssuer().asX500Principal();
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
|
@ -677,8 +661,6 @@ public class X509CertImpl extends X509Certificate implements DerEncoder {
|
||||||
* @return the start date of the validity period.
|
* @return the start date of the validity period.
|
||||||
*/
|
*/
|
||||||
public Date getNotBefore() {
|
public Date getNotBefore() {
|
||||||
if (info == null)
|
|
||||||
return null;
|
|
||||||
return info.getValidity().getNotBefore();
|
return info.getValidity().getNotBefore();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -688,8 +670,6 @@ public class X509CertImpl extends X509Certificate implements DerEncoder {
|
||||||
* @return the end date of the validity period.
|
* @return the end date of the validity period.
|
||||||
*/
|
*/
|
||||||
public Date getNotAfter() {
|
public Date getNotAfter() {
|
||||||
if (info == null)
|
|
||||||
return null;
|
|
||||||
return info.getValidity().getNotAfter();
|
return info.getValidity().getNotAfter();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -702,10 +682,7 @@ public class X509CertImpl extends X509Certificate implements DerEncoder {
|
||||||
* @exception CertificateEncodingException if an encoding error occurs.
|
* @exception CertificateEncodingException if an encoding error occurs.
|
||||||
*/
|
*/
|
||||||
public byte[] getTBSCertificate() throws CertificateEncodingException {
|
public byte[] getTBSCertificate() throws CertificateEncodingException {
|
||||||
if (info != null) {
|
return info.getEncodedInfo();
|
||||||
return info.getEncodedInfo();
|
|
||||||
} else
|
|
||||||
throw new CertificateEncodingException("Uninitialized certificate");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -766,8 +743,6 @@ public class X509CertImpl extends X509Certificate implements DerEncoder {
|
||||||
* @return the Issuer Unique Identity.
|
* @return the Issuer Unique Identity.
|
||||||
*/
|
*/
|
||||||
public boolean[] getIssuerUniqueID() {
|
public boolean[] getIssuerUniqueID() {
|
||||||
if (info == null)
|
|
||||||
return null;
|
|
||||||
UniqueIdentity id = info.getIssuerUniqueId();
|
UniqueIdentity id = info.getIssuerUniqueId();
|
||||||
if (id == null)
|
if (id == null)
|
||||||
return null;
|
return null;
|
||||||
|
@ -781,8 +756,6 @@ public class X509CertImpl extends X509Certificate implements DerEncoder {
|
||||||
* @return the Subject Unique Identity.
|
* @return the Subject Unique Identity.
|
||||||
*/
|
*/
|
||||||
public boolean[] getSubjectUniqueID() {
|
public boolean[] getSubjectUniqueID() {
|
||||||
if (info == null)
|
|
||||||
return null;
|
|
||||||
UniqueIdentity id = info.getSubjectUniqueId();
|
UniqueIdentity id = info.getSubjectUniqueId();
|
||||||
if (id == null)
|
if (id == null)
|
||||||
return null;
|
return null;
|
||||||
|
@ -935,8 +908,6 @@ public class X509CertImpl extends X509Certificate implements DerEncoder {
|
||||||
* not supported, otherwise return false.
|
* not supported, otherwise return false.
|
||||||
*/
|
*/
|
||||||
public boolean hasUnsupportedCriticalExtension() {
|
public boolean hasUnsupportedCriticalExtension() {
|
||||||
if (info == null)
|
|
||||||
return false;
|
|
||||||
CertificateExtensions exts = info.getExtensions();
|
CertificateExtensions exts = info.getExtensions();
|
||||||
if (exts == null)
|
if (exts == null)
|
||||||
return false;
|
return false;
|
||||||
|
@ -952,9 +923,6 @@ public class X509CertImpl extends X509Certificate implements DerEncoder {
|
||||||
* certificate that are marked critical.
|
* certificate that are marked critical.
|
||||||
*/
|
*/
|
||||||
public Set<String> getCriticalExtensionOIDs() {
|
public Set<String> getCriticalExtensionOIDs() {
|
||||||
if (info == null) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
try {
|
try {
|
||||||
CertificateExtensions exts = info.getExtensions();
|
CertificateExtensions exts = info.getExtensions();
|
||||||
if (exts == null) {
|
if (exts == null) {
|
||||||
|
@ -981,9 +949,6 @@ public class X509CertImpl extends X509Certificate implements DerEncoder {
|
||||||
* certificate that are NOT marked critical.
|
* certificate that are NOT marked critical.
|
||||||
*/
|
*/
|
||||||
public Set<String> getNonCriticalExtensionOIDs() {
|
public Set<String> getNonCriticalExtensionOIDs() {
|
||||||
if (info == null) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
try {
|
try {
|
||||||
CertificateExtensions exts = info.getExtensions();
|
CertificateExtensions exts = info.getExtensions();
|
||||||
if (exts == null) {
|
if (exts == null) {
|
||||||
|
@ -1010,9 +975,6 @@ public class X509CertImpl extends X509Certificate implements DerEncoder {
|
||||||
* extension
|
* extension
|
||||||
*/
|
*/
|
||||||
public Extension getExtension(ObjectIdentifier oid) {
|
public Extension getExtension(ObjectIdentifier oid) {
|
||||||
if (info == null) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
CertificateExtensions extensions = info.getExtensions();
|
CertificateExtensions extensions = info.getExtensions();
|
||||||
if (extensions != null) {
|
if (extensions != null) {
|
||||||
Extension ex = extensions.getExtension(oid.toString());
|
Extension ex = extensions.getExtension(oid.toString());
|
||||||
|
@ -1031,9 +993,6 @@ public class X509CertImpl extends X509Certificate implements DerEncoder {
|
||||||
}
|
}
|
||||||
|
|
||||||
public Extension getUnparseableExtension(ObjectIdentifier oid) {
|
public Extension getUnparseableExtension(ObjectIdentifier oid) {
|
||||||
if (info == null) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
CertificateExtensions extensions = info.getExtensions();
|
CertificateExtensions extensions = info.getExtensions();
|
||||||
if (extensions == null) {
|
if (extensions == null) {
|
||||||
return null;
|
return null;
|
||||||
|
@ -1047,6 +1006,8 @@ public class X509CertImpl extends X509Certificate implements DerEncoder {
|
||||||
* oid String.
|
* oid String.
|
||||||
*
|
*
|
||||||
* @param oid the Object Identifier value for the extension.
|
* @param oid the Object Identifier value for the extension.
|
||||||
|
* @return the DER-encoded extension value, or {@code null} if
|
||||||
|
* the extensions are not present or the value is not found
|
||||||
*/
|
*/
|
||||||
public byte[] getExtensionValue(String oid) {
|
public byte[] getExtensionValue(String oid) {
|
||||||
try {
|
try {
|
||||||
|
@ -1054,13 +1015,11 @@ public class X509CertImpl extends X509Certificate implements DerEncoder {
|
||||||
String extAlias = OIDMap.getName(findOID);
|
String extAlias = OIDMap.getName(findOID);
|
||||||
Extension certExt = null;
|
Extension certExt = null;
|
||||||
CertificateExtensions exts = info.getExtensions();
|
CertificateExtensions exts = info.getExtensions();
|
||||||
|
if (exts == null) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
if (extAlias == null) { // may be unknown
|
if (extAlias == null) { // may be unknown
|
||||||
// get the extensions, search through' for this oid
|
// get the extensions, search through' for this oid
|
||||||
if (exts == null) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
for (Extension ex : exts.getAllExtensions()) {
|
for (Extension ex : exts.getAllExtensions()) {
|
||||||
ObjectIdentifier inCertOID = ex.getExtensionId();
|
ObjectIdentifier inCertOID = ex.getExtensionId();
|
||||||
if (inCertOID.equals(findOID)) {
|
if (inCertOID.equals(findOID)) {
|
||||||
|
@ -1069,12 +1028,10 @@ public class X509CertImpl extends X509Certificate implements DerEncoder {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else { // there's subclass that can handle this extension
|
} else { // there's subclass that can handle this extension
|
||||||
certExt = getInfo().getExtensions().getExtension(extAlias);
|
certExt = exts.getExtension(extAlias);
|
||||||
}
|
}
|
||||||
if (certExt == null) {
|
if (certExt == null) {
|
||||||
if (exts != null) {
|
certExt = exts.getUnparseableExtensions().get(oid);
|
||||||
certExt = exts.getUnparseableExtensions().get(oid);
|
|
||||||
}
|
|
||||||
if (certExt == null) {
|
if (certExt == null) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
@ -1098,8 +1055,12 @@ public class X509CertImpl extends X509Certificate implements DerEncoder {
|
||||||
*/
|
*/
|
||||||
public boolean[] getKeyUsage() {
|
public boolean[] getKeyUsage() {
|
||||||
try {
|
try {
|
||||||
|
CertificateExtensions extensions = info.getExtensions();
|
||||||
|
if (extensions == null) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
KeyUsageExtension certExt = (KeyUsageExtension)
|
KeyUsageExtension certExt = (KeyUsageExtension)
|
||||||
getInfo().getExtensions().getExtension(KeyUsageExtension.NAME);
|
extensions.getExtension(KeyUsageExtension.NAME);
|
||||||
if (certExt == null)
|
if (certExt == null)
|
||||||
return null;
|
return null;
|
||||||
|
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2002, 2022, Oracle and/or its affiliates. All rights reserved.
|
* Copyright (c) 2002, 2025, Oracle and/or its affiliates. All rights reserved.
|
||||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||||
*
|
*
|
||||||
* This code is free software; you can redistribute it and/or modify it
|
* This code is free software; you can redistribute it and/or modify it
|
||||||
|
@ -36,6 +36,7 @@ import java.util.List;
|
||||||
import jdk.test.lib.security.CertUtils;
|
import jdk.test.lib.security.CertUtils;
|
||||||
import sun.security.util.*;
|
import sun.security.util.*;
|
||||||
import sun.security.x509.X509CertImpl;
|
import sun.security.x509.X509CertImpl;
|
||||||
|
import sun.security.x509.X509CertInfo;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Certificate 1:
|
* Certificate 1:
|
||||||
|
@ -225,7 +226,7 @@ public class TestHostnameChecker {
|
||||||
}
|
}
|
||||||
|
|
||||||
private static X509Certificate mock(String domain) {
|
private static X509Certificate mock(String domain) {
|
||||||
return new X509CertImpl(null, null, null, new byte[0]) {
|
return new X509CertImpl(new X509CertInfo(), null, null, new byte[0]) {
|
||||||
@Override
|
@Override
|
||||||
public Collection<List<?>> getSubjectAlternativeNames() {
|
public Collection<List<?>> getSubjectAlternativeNames() {
|
||||||
return List.of(List.of(2, domain));
|
return List.of(List.of(2, domain));
|
||||||
|
|
201
test/jdk/sun/security/x509/X509CertImpl/CertExtensions.java
Normal file
201
test/jdk/sun/security/x509/X509CertImpl/CertExtensions.java
Normal file
|
@ -0,0 +1,201 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2025, Oracle and/or its affiliates. All rights reserved.
|
||||||
|
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||||
|
*
|
||||||
|
* This code is free software; you can redistribute it and/or modify it
|
||||||
|
* under the terms of the GNU General Public License version 2 only, as
|
||||||
|
* published by the Free Software Foundation.
|
||||||
|
*
|
||||||
|
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||||
|
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||||
|
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||||
|
* version 2 for more details (a copy is included in the LICENSE file that
|
||||||
|
* accompanied this code).
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License version
|
||||||
|
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||||
|
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||||
|
*
|
||||||
|
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||||
|
* or visit www.oracle.com if you need additional information or have any
|
||||||
|
* questions.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @test
|
||||||
|
* @bug 8346094
|
||||||
|
* @summary validating getExtensionValue and getKeyUsage with specified and
|
||||||
|
* unspecified extensions on the X509Certificate.
|
||||||
|
* @library /test/lib
|
||||||
|
* @modules java.base/sun.security.x509
|
||||||
|
* java.base/sun.security.util
|
||||||
|
*/
|
||||||
|
|
||||||
|
import jdk.test.lib.Asserts;
|
||||||
|
import sun.security.util.ObjectIdentifier;
|
||||||
|
import sun.security.x509.*;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.math.BigInteger;
|
||||||
|
import java.security.*;
|
||||||
|
import java.util.Calendar;
|
||||||
|
import java.util.Date;
|
||||||
|
import java.util.TimeZone;
|
||||||
|
|
||||||
|
|
||||||
|
public class CertExtensions {
|
||||||
|
|
||||||
|
public static void main(String[] args) throws Exception {
|
||||||
|
X509CertImpl x509Certimpl = createCertificate();
|
||||||
|
/**
|
||||||
|
* Certificate is created without extensions. Invoking getExtensionValue
|
||||||
|
* with oid must return NULL else it is incorrect
|
||||||
|
*/
|
||||||
|
Asserts.assertNull(x509Certimpl.getExtensionValue("2.5.29.17"));
|
||||||
|
/**
|
||||||
|
* Certificate is created with extensions. Invoking getExtensionValue
|
||||||
|
* with oid must not return NULL else it is incorrect
|
||||||
|
*/
|
||||||
|
x509Certimpl.getInfo().setExtensions(createCertificateExtensions(
|
||||||
|
x509Certimpl.getInfo().getKey().getKey()));
|
||||||
|
Asserts.assertNotNull(x509Certimpl.getExtensionValue("2.5.29.17"));
|
||||||
|
/**
|
||||||
|
* Certificate is created with extensions. Invoking getExtensionValue
|
||||||
|
* with invalid oid must return NULL else it is incorrect
|
||||||
|
*/
|
||||||
|
Asserts.assertNull(x509Certimpl.getExtensionValue("1.2.3.4"));
|
||||||
|
/**
|
||||||
|
* Certificate is created with extensions. Invoking getKeyUsage
|
||||||
|
* must not return NULL else it is incorrect
|
||||||
|
*/
|
||||||
|
Asserts.assertNotNull(x509Certimpl.getKeyUsage());
|
||||||
|
/**
|
||||||
|
* Certificate is created without extensions. Invoking getKeyUsage
|
||||||
|
* must return NULL else it is incorrect
|
||||||
|
*/
|
||||||
|
x509Certimpl.getInfo().setExtensions(null);
|
||||||
|
Asserts.assertNull(x509Certimpl.getKeyUsage());
|
||||||
|
}
|
||||||
|
|
||||||
|
private static X509CertImpl createCertificate() throws Exception {
|
||||||
|
X509CertImpl x509Certimpl = null;
|
||||||
|
try {
|
||||||
|
X509CertInfo x509CertInfo = new X509CertInfo();
|
||||||
|
x509CertInfo.setVersion(new CertificateVersion(CertificateVersion.V3));
|
||||||
|
|
||||||
|
// Generate Key Pair (RSA)
|
||||||
|
KeyPairGenerator keyPairGenerator = KeyPairGenerator.getInstance("RSA");
|
||||||
|
keyPairGenerator.initialize(2048);
|
||||||
|
KeyPair keyPair = keyPairGenerator.generateKeyPair();
|
||||||
|
PrivateKey privateKey = keyPair.getPrivate();
|
||||||
|
PublicKey publicKey = keyPair.getPublic();
|
||||||
|
x509CertInfo.setKey(new CertificateX509Key(publicKey));
|
||||||
|
|
||||||
|
// Create and set the DN name for Subject and Issuer.
|
||||||
|
X500Name subject = new X500Name("CN=www.Subject.com, O=MyOrg, OU=LocalBiz, L=XYZ, S=YY, C=XX");
|
||||||
|
X500Name issuer = new X500Name("CN=www.Issuer.com, O=Oracle,OU=Java,L=XYZ,S=YY, C=XX");
|
||||||
|
x509CertInfo.setIssuer(issuer);
|
||||||
|
x509CertInfo.setSubject(subject);
|
||||||
|
|
||||||
|
// create and set the subject and issuer unique identity
|
||||||
|
byte[] issuerId = {1, 2, 3, 4, 5};
|
||||||
|
byte[] subjectId = {6, 7, 8, 9, 10};
|
||||||
|
x509CertInfo.setSubjectUniqueId(new UniqueIdentity(subjectId));
|
||||||
|
x509CertInfo.setIssuerUniqueId(new UniqueIdentity(issuerId));
|
||||||
|
|
||||||
|
// create and set the serial number
|
||||||
|
BigInteger serialNumber = BigInteger.valueOf(new SecureRandom().nextInt(Integer.MAX_VALUE));
|
||||||
|
x509CertInfo.setSerialNumber(new CertificateSerialNumber(serialNumber));
|
||||||
|
|
||||||
|
// create and set the validity interval
|
||||||
|
Date notBefore = new Date(); // Valid from now
|
||||||
|
Date notAfter = new Date(System.currentTimeMillis() + 365L * 24 * 60 * 60 * 1000); // Valid for 1 year
|
||||||
|
x509CertInfo.setValidity(new CertificateValidity(notBefore, notAfter));
|
||||||
|
|
||||||
|
// Create Certificate Info which is the representation of X509 Certificate.
|
||||||
|
x509CertInfo.setAlgorithmId(new CertificateAlgorithmId(AlgorithmId.get("SHA256withRSA")));
|
||||||
|
|
||||||
|
// Sign the certificate
|
||||||
|
Signature signature = Signature.getInstance("SHA256withRSA");
|
||||||
|
signature.initSign(privateKey);
|
||||||
|
signature.update(x509CertInfo.getEncodedInfo());
|
||||||
|
byte[] signedData = signature.sign();
|
||||||
|
byte[] signedCert = {};
|
||||||
|
|
||||||
|
x509Certimpl = new X509CertImpl(x509CertInfo,
|
||||||
|
AlgorithmId.get("SHA256withRSA"), signedData, signedCert);
|
||||||
|
} catch (Exception e) {
|
||||||
|
System.out.println("caught exception while creating the certificate : " + e.getMessage());
|
||||||
|
throw e;
|
||||||
|
}
|
||||||
|
return x509Certimpl;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static sun.security.x509.CertificateExtensions createCertificateExtensions
|
||||||
|
(PublicKey publicKey) throws IOException, NoSuchAlgorithmException {
|
||||||
|
// Create Extensions
|
||||||
|
sun.security.x509.CertificateExtensions certificateExtensions =
|
||||||
|
new sun.security.x509.CertificateExtensions();
|
||||||
|
|
||||||
|
GeneralNameInterface mailInf = new RFC822Name("test@Oracle.com");
|
||||||
|
GeneralName mail = new GeneralName(mailInf);
|
||||||
|
GeneralNameInterface dnsInf = new DNSName("Oracle.com");
|
||||||
|
GeneralName dns = new GeneralName(dnsInf);
|
||||||
|
GeneralNameInterface uriInf = new URIName("http://www.Oracle.com");
|
||||||
|
GeneralName uri = new GeneralName(uriInf);
|
||||||
|
|
||||||
|
// localhost
|
||||||
|
byte[] address = new byte[]{127, 0, 0, 1};
|
||||||
|
|
||||||
|
GeneralNameInterface ipInf = new IPAddressName(address);
|
||||||
|
GeneralName ip = new GeneralName(ipInf);
|
||||||
|
|
||||||
|
GeneralNameInterface oidInf = new OIDName(ObjectIdentifier.of("1.2.3.4"));
|
||||||
|
GeneralName oid = new GeneralName(oidInf);
|
||||||
|
|
||||||
|
|
||||||
|
GeneralNames subjectNames = new GeneralNames();
|
||||||
|
subjectNames.add(mail);
|
||||||
|
subjectNames.add(dns);
|
||||||
|
subjectNames.add(uri);
|
||||||
|
SubjectAlternativeNameExtension subjectName = new SubjectAlternativeNameExtension(subjectNames);
|
||||||
|
|
||||||
|
GeneralNames issuerNames = new GeneralNames();
|
||||||
|
issuerNames.add(ip);
|
||||||
|
issuerNames.add(oid);
|
||||||
|
IssuerAlternativeNameExtension issuerName = new IssuerAlternativeNameExtension(issuerNames);
|
||||||
|
Calendar cal = Calendar.getInstance(TimeZone.getTimeZone("America/Los_Angeles"));
|
||||||
|
cal.set(2014, 03, 10, 12, 30, 30);
|
||||||
|
cal.set(2000, 11, 15, 12, 30, 30);
|
||||||
|
Date lastDate = cal.getTime();
|
||||||
|
Date firstDate = new Date();
|
||||||
|
PrivateKeyUsageExtension pkusage = new PrivateKeyUsageExtension(firstDate, lastDate);
|
||||||
|
|
||||||
|
KeyUsageExtension usage = new KeyUsageExtension();
|
||||||
|
usage.set(KeyUsageExtension.CRL_SIGN, true);
|
||||||
|
usage.set(KeyUsageExtension.DIGITAL_SIGNATURE, true);
|
||||||
|
usage.set(KeyUsageExtension.NON_REPUDIATION, true);
|
||||||
|
MessageDigest md = MessageDigest.getInstance("SHA");
|
||||||
|
|
||||||
|
byte[] keyId = md.digest(publicKey.getEncoded());
|
||||||
|
KeyIdentifier kid = new KeyIdentifier(keyId);
|
||||||
|
SerialNumber sn = new SerialNumber(42);
|
||||||
|
AuthorityKeyIdentifierExtension aki = new AuthorityKeyIdentifierExtension(kid, subjectNames, sn);
|
||||||
|
|
||||||
|
SubjectKeyIdentifierExtension ski = new SubjectKeyIdentifierExtension(keyId);
|
||||||
|
|
||||||
|
BasicConstraintsExtension cons = new BasicConstraintsExtension(true, 10);
|
||||||
|
|
||||||
|
PolicyConstraintsExtension pce = new PolicyConstraintsExtension(2, 4);
|
||||||
|
|
||||||
|
certificateExtensions.setExtension(SubjectAlternativeNameExtension.NAME, subjectName);
|
||||||
|
certificateExtensions.setExtension(IssuerAlternativeNameExtension.NAME, issuerName);
|
||||||
|
certificateExtensions.setExtension(PrivateKeyUsageExtension.NAME, pkusage);
|
||||||
|
certificateExtensions.setExtension(KeyUsageExtension.NAME, usage);
|
||||||
|
certificateExtensions.setExtension(AuthorityKeyIdentifierExtension.NAME, aki);
|
||||||
|
certificateExtensions.setExtension(SubjectKeyIdentifierExtension.NAME, ski);
|
||||||
|
certificateExtensions.setExtension(BasicConstraintsExtension.NAME, cons);
|
||||||
|
certificateExtensions.setExtension(PolicyConstraintsExtension.NAME, pce);
|
||||||
|
return certificateExtensions;
|
||||||
|
}
|
||||||
|
}
|
Loading…
Add table
Add a link
Reference in a new issue