6890876: jarsigner can add CRL info into signed jar
Reviewed-by: mullan
This commit is contained in:
parent
a94d06f6b7
commit
7c6813eb7a
@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright 2003 Sun Microsystems, Inc. All Rights Reserved.
|
* Copyright 2003-2010 Sun Microsystems, Inc. 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
|
||||||
@ -26,7 +26,9 @@
|
|||||||
package com.sun.jarsigner;
|
package com.sun.jarsigner;
|
||||||
|
|
||||||
import java.net.URI;
|
import java.net.URI;
|
||||||
|
import java.security.cert.X509CRL;
|
||||||
import java.security.cert.X509Certificate;
|
import java.security.cert.X509Certificate;
|
||||||
|
import java.util.Set;
|
||||||
import java.util.zip.ZipFile;
|
import java.util.zip.ZipFile;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -80,6 +82,13 @@ public interface ContentSignerParameters {
|
|||||||
*/
|
*/
|
||||||
public X509Certificate[] getSignerCertificateChain();
|
public X509Certificate[] getSignerCertificateChain();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Retrieves the signer's X.509 CRLs.
|
||||||
|
*
|
||||||
|
* @return An unmodifiable set of X.509 CRLs (never <code>null</code>)
|
||||||
|
*/
|
||||||
|
public Set<X509CRL> getCRLs();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Retrieves the content that was signed.
|
* Retrieves the content that was signed.
|
||||||
* The content is the JAR file's signature file.
|
* The content is the JAR file's signature file.
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright 2003-2004 Sun Microsystems, Inc. All Rights Reserved.
|
* Copyright 2003-2010 Sun Microsystems, Inc. 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
|
||||||
@ -26,7 +26,10 @@
|
|||||||
package java.security;
|
package java.security;
|
||||||
|
|
||||||
import java.io.Serializable;
|
import java.io.Serializable;
|
||||||
|
import java.security.cert.CRL;
|
||||||
import java.security.cert.CertPath;
|
import java.security.cert.CertPath;
|
||||||
|
import sun.misc.JavaSecurityCodeSignerAccess;
|
||||||
|
import sun.misc.SharedSecrets;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This class encapsulates information about a code signer.
|
* This class encapsulates information about a code signer.
|
||||||
@ -163,4 +166,43 @@ public final class CodeSigner implements Serializable {
|
|||||||
sb.append(")");
|
sb.append(")");
|
||||||
return sb.toString();
|
return sb.toString();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// A private attribute attached to this CodeSigner object. Can be accessed
|
||||||
|
// through SharedSecrets.getJavaSecurityCodeSignerAccess().[g|s]etCRLs
|
||||||
|
//
|
||||||
|
// Currently called in SignatureFileVerifier.getSigners
|
||||||
|
private transient CRL[] crls;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets the CRLs attached
|
||||||
|
* @param crls, null to clear
|
||||||
|
*/
|
||||||
|
void setCRLs(CRL[] crls) {
|
||||||
|
this.crls = crls;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the CRLs attached
|
||||||
|
* @return the crls, initially null
|
||||||
|
*/
|
||||||
|
CRL[] getCRLs() {
|
||||||
|
return crls;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Set up JavaSecurityCodeSignerAccess in SharedSecrets
|
||||||
|
static {
|
||||||
|
SharedSecrets.setJavaSecurityCodeSignerAccess(
|
||||||
|
new JavaSecurityCodeSignerAccess() {
|
||||||
|
@Override
|
||||||
|
public void setCRLs(CodeSigner signer, CRL[] crls) {
|
||||||
|
signer.setCRLs(crls);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public CRL[] getCRLs(CodeSigner signer) {
|
||||||
|
return signer.getCRLs();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright 1997-2009 Sun Microsystems, Inc. All Rights Reserved.
|
* Copyright 1997-2010 Sun Microsystems, Inc. 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
|
||||||
@ -27,7 +27,6 @@ package java.util.jar;
|
|||||||
|
|
||||||
import java.io.*;
|
import java.io.*;
|
||||||
import java.util.*;
|
import java.util.*;
|
||||||
import java.util.zip.*;
|
|
||||||
import java.security.*;
|
import java.security.*;
|
||||||
import java.security.cert.CertificateException;
|
import java.security.cert.CertificateException;
|
||||||
|
|
||||||
|
@ -0,0 +1,33 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2010 Sun Microsystems, Inc. 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. Sun designates this
|
||||||
|
* particular file as subject to the "Classpath" exception as provided
|
||||||
|
* by Sun in the LICENSE file that accompanied this code.
|
||||||
|
*
|
||||||
|
* 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
|
||||||
|
* CA 95054 USA or visit www.sun.com if you need additional information or
|
||||||
|
* have any questions.
|
||||||
|
*/
|
||||||
|
package sun.misc;
|
||||||
|
|
||||||
|
import java.security.CodeSigner;
|
||||||
|
import java.security.cert.CRL;
|
||||||
|
|
||||||
|
public interface JavaSecurityCodeSignerAccess {
|
||||||
|
void setCRLs(CodeSigner signer, CRL[] crls);
|
||||||
|
CRL[] getCRLs(CodeSigner signer);
|
||||||
|
}
|
@ -27,8 +27,8 @@ package sun.misc;
|
|||||||
|
|
||||||
import java.util.jar.JarFile;
|
import java.util.jar.JarFile;
|
||||||
import java.io.Console;
|
import java.io.Console;
|
||||||
import java.io.File;
|
|
||||||
import java.io.FileDescriptor;
|
import java.io.FileDescriptor;
|
||||||
|
import java.security.CodeSigner;
|
||||||
import java.security.ProtectionDomain;
|
import java.security.ProtectionDomain;
|
||||||
|
|
||||||
/** A repository of "shared secrets", which are a mechanism for
|
/** A repository of "shared secrets", which are a mechanism for
|
||||||
@ -49,6 +49,7 @@ public class SharedSecrets {
|
|||||||
private static JavaNioAccess javaNioAccess;
|
private static JavaNioAccess javaNioAccess;
|
||||||
private static JavaIOFileDescriptorAccess javaIOFileDescriptorAccess;
|
private static JavaIOFileDescriptorAccess javaIOFileDescriptorAccess;
|
||||||
private static JavaSecurityProtectionDomainAccess javaSecurityProtectionDomainAccess;
|
private static JavaSecurityProtectionDomainAccess javaSecurityProtectionDomainAccess;
|
||||||
|
private static JavaSecurityCodeSignerAccess javaSecurityCodeSignerAccess;
|
||||||
|
|
||||||
public static JavaUtilJarAccess javaUtilJarAccess() {
|
public static JavaUtilJarAccess javaUtilJarAccess() {
|
||||||
if (javaUtilJarAccess == null) {
|
if (javaUtilJarAccess == null) {
|
||||||
@ -126,4 +127,16 @@ public class SharedSecrets {
|
|||||||
unsafe.ensureClassInitialized(ProtectionDomain.class);
|
unsafe.ensureClassInitialized(ProtectionDomain.class);
|
||||||
return javaSecurityProtectionDomainAccess;
|
return javaSecurityProtectionDomainAccess;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static void setJavaSecurityCodeSignerAccess
|
||||||
|
(JavaSecurityCodeSignerAccess jscsa) {
|
||||||
|
javaSecurityCodeSignerAccess = jscsa;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static JavaSecurityCodeSignerAccess
|
||||||
|
getJavaSecurityCodeSignerAccess() {
|
||||||
|
if (javaSecurityCodeSignerAccess == null)
|
||||||
|
unsafe.ensureClassInitialized(CodeSigner.class);
|
||||||
|
return javaSecurityCodeSignerAccess;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright 1996-2006 Sun Microsystems, Inc. All Rights Reserved.
|
* Copyright 1996-2010 Sun Microsystems, Inc. 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
|
||||||
@ -28,7 +28,6 @@ package sun.security.pkcs;
|
|||||||
import java.io.*;
|
import java.io.*;
|
||||||
import java.math.BigInteger;
|
import java.math.BigInteger;
|
||||||
import java.util.*;
|
import java.util.*;
|
||||||
import java.security.cert.Certificate;
|
|
||||||
import java.security.cert.X509Certificate;
|
import java.security.cert.X509Certificate;
|
||||||
import java.security.cert.CertificateException;
|
import java.security.cert.CertificateException;
|
||||||
import java.security.cert.X509CRL;
|
import java.security.cert.X509CRL;
|
||||||
@ -173,20 +172,30 @@ public class PKCS7 {
|
|||||||
* @param digestAlgorithmIds the message digest algorithm identifiers.
|
* @param digestAlgorithmIds the message digest algorithm identifiers.
|
||||||
* @param contentInfo the content information.
|
* @param contentInfo the content information.
|
||||||
* @param certificates an array of X.509 certificates.
|
* @param certificates an array of X.509 certificates.
|
||||||
|
* @param crls an array of CRLs
|
||||||
* @param signerInfos an array of signer information.
|
* @param signerInfos an array of signer information.
|
||||||
*/
|
*/
|
||||||
public PKCS7(AlgorithmId[] digestAlgorithmIds,
|
public PKCS7(AlgorithmId[] digestAlgorithmIds,
|
||||||
ContentInfo contentInfo,
|
ContentInfo contentInfo,
|
||||||
X509Certificate[] certificates,
|
X509Certificate[] certificates,
|
||||||
|
X509CRL[] crls,
|
||||||
SignerInfo[] signerInfos) {
|
SignerInfo[] signerInfos) {
|
||||||
|
|
||||||
version = BigInteger.ONE;
|
version = BigInteger.ONE;
|
||||||
this.digestAlgorithmIds = digestAlgorithmIds;
|
this.digestAlgorithmIds = digestAlgorithmIds;
|
||||||
this.contentInfo = contentInfo;
|
this.contentInfo = contentInfo;
|
||||||
this.certificates = certificates;
|
this.certificates = certificates;
|
||||||
|
this.crls = crls;
|
||||||
this.signerInfos = signerInfos;
|
this.signerInfos = signerInfos;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public PKCS7(AlgorithmId[] digestAlgorithmIds,
|
||||||
|
ContentInfo contentInfo,
|
||||||
|
X509Certificate[] certificates,
|
||||||
|
SignerInfo[] signerInfos) {
|
||||||
|
this(digestAlgorithmIds, contentInfo, certificates, null, signerInfos);
|
||||||
|
}
|
||||||
|
|
||||||
private void parseNetscapeCertChain(DerValue val)
|
private void parseNetscapeCertChain(DerValue val)
|
||||||
throws ParsingException, IOException {
|
throws ParsingException, IOException {
|
||||||
DerInputStream dis = new DerInputStream(val.toByteArray());
|
DerInputStream dis = new DerInputStream(val.toByteArray());
|
||||||
@ -312,7 +321,7 @@ public class PKCS7 {
|
|||||||
ByteArrayInputStream bais = null;
|
ByteArrayInputStream bais = null;
|
||||||
try {
|
try {
|
||||||
if (certfac == null)
|
if (certfac == null)
|
||||||
crls[i] = (X509CRL) new X509CRLImpl(crlVals[i]);
|
crls[i] = new X509CRLImpl(crlVals[i]);
|
||||||
else {
|
else {
|
||||||
byte[] encoded = crlVals[i].toByteArray();
|
byte[] encoded = crlVals[i].toByteArray();
|
||||||
bais = new ByteArrayInputStream(encoded);
|
bais = new ByteArrayInputStream(encoded);
|
||||||
@ -480,7 +489,30 @@ public class PKCS7 {
|
|||||||
signedData.putOrderedSetOf((byte)0xA0, implCerts);
|
signedData.putOrderedSetOf((byte)0xA0, implCerts);
|
||||||
}
|
}
|
||||||
|
|
||||||
// no crls (OPTIONAL field)
|
// CRLs (optional)
|
||||||
|
if (crls != null && crls.length != 0) {
|
||||||
|
// cast to X509CRLImpl[] since X509CRLImpl implements DerEncoder
|
||||||
|
Set<X509CRLImpl> implCRLs = new HashSet<X509CRLImpl>(crls.length);
|
||||||
|
for (X509CRL crl: crls) {
|
||||||
|
if (crl instanceof X509CRLImpl)
|
||||||
|
implCRLs.add((X509CRLImpl) crl);
|
||||||
|
else {
|
||||||
|
try {
|
||||||
|
byte[] encoded = crl.getEncoded();
|
||||||
|
implCRLs.add(new X509CRLImpl(encoded));
|
||||||
|
} catch (CRLException ce) {
|
||||||
|
IOException ie = new IOException(ce.getMessage());
|
||||||
|
ie.initCause(ce);
|
||||||
|
throw ie;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Add the CRL set (tagged with [1] IMPLICIT)
|
||||||
|
// to the signed data
|
||||||
|
signedData.putOrderedSetOf((byte)0xA1,
|
||||||
|
implCRLs.toArray(new X509CRLImpl[implCRLs.size()]));
|
||||||
|
}
|
||||||
|
|
||||||
// signerInfos
|
// signerInfos
|
||||||
signedData.putOrderedSetOf(DerValue.tag_Set, signerInfos);
|
signedData.putOrderedSetOf(DerValue.tag_Set, signerInfos);
|
||||||
|
@ -26,6 +26,7 @@
|
|||||||
package sun.security.tools;
|
package sun.security.tools;
|
||||||
|
|
||||||
import java.io.*;
|
import java.io.*;
|
||||||
|
import java.security.cert.X509CRL;
|
||||||
import java.util.*;
|
import java.util.*;
|
||||||
import java.util.zip.*;
|
import java.util.zip.*;
|
||||||
import java.util.jar.*;
|
import java.util.jar.*;
|
||||||
@ -35,6 +36,7 @@ import java.net.URISyntaxException;
|
|||||||
import java.text.Collator;
|
import java.text.Collator;
|
||||||
import java.text.MessageFormat;
|
import java.text.MessageFormat;
|
||||||
import java.security.cert.Certificate;
|
import java.security.cert.Certificate;
|
||||||
|
import java.security.cert.CRL;
|
||||||
import java.security.cert.X509Certificate;
|
import java.security.cert.X509Certificate;
|
||||||
import java.security.cert.CertificateException;
|
import java.security.cert.CertificateException;
|
||||||
import java.security.*;
|
import java.security.*;
|
||||||
@ -56,6 +58,7 @@ import java.util.Map.Entry;
|
|||||||
import sun.security.x509.*;
|
import sun.security.x509.*;
|
||||||
import sun.security.util.*;
|
import sun.security.util.*;
|
||||||
import sun.misc.BASE64Encoder;
|
import sun.misc.BASE64Encoder;
|
||||||
|
import sun.misc.SharedSecrets;
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -114,14 +117,16 @@ public class JarSigner {
|
|||||||
static final int SIGNED_BY_ALIAS = 0x08; // signer is in alias list
|
static final int SIGNED_BY_ALIAS = 0x08; // signer is in alias list
|
||||||
|
|
||||||
X509Certificate[] certChain; // signer's cert chain (when composing)
|
X509Certificate[] certChain; // signer's cert chain (when composing)
|
||||||
|
Set<X509CRL> crls; // signer provided CRLs
|
||||||
PrivateKey privateKey; // private key
|
PrivateKey privateKey; // private key
|
||||||
KeyStore store; // the keystore specified by -keystore
|
KeyStore store; // the keystore specified by -keystore
|
||||||
// or the default keystore, never null
|
// or the default keystore, never null
|
||||||
|
|
||||||
String keystore; // key store file
|
String keystore; // key store file
|
||||||
|
List<String> crlfiles = new ArrayList<String>(); // CRL files to add
|
||||||
boolean nullStream = false; // null keystore input stream (NONE)
|
boolean nullStream = false; // null keystore input stream (NONE)
|
||||||
boolean token = false; // token-based keystore
|
boolean token = false; // token-based keystore
|
||||||
String jarfile; // jar file to sign or verify
|
String jarfile; // jar files to sign or verify
|
||||||
String alias; // alias to sign jar with
|
String alias; // alias to sign jar with
|
||||||
List<String> ckaliases = new ArrayList<String>(); // aliases in -verify
|
List<String> ckaliases = new ArrayList<String>(); // aliases in -verify
|
||||||
char[] storepass; // keystore password
|
char[] storepass; // keystore password
|
||||||
@ -146,6 +151,7 @@ public class JarSigner {
|
|||||||
boolean signManifest = true; // "sign" the whole manifest
|
boolean signManifest = true; // "sign" the whole manifest
|
||||||
boolean externalSF = true; // leave the .SF out of the PKCS7 block
|
boolean externalSF = true; // leave the .SF out of the PKCS7 block
|
||||||
boolean strict = false; // treat warnings as error
|
boolean strict = false; // treat warnings as error
|
||||||
|
boolean autoCRL = false; // Automatcially add CRL defined in cert
|
||||||
|
|
||||||
// read zip entry raw bytes
|
// read zip entry raw bytes
|
||||||
private ByteArrayOutputStream baos = new ByteArrayOutputStream(2048);
|
private ByteArrayOutputStream baos = new ByteArrayOutputStream(2048);
|
||||||
@ -226,6 +232,29 @@ public class JarSigner {
|
|||||||
} else {
|
} else {
|
||||||
loadKeyStore(keystore, true);
|
loadKeyStore(keystore, true);
|
||||||
getAliasInfo(alias);
|
getAliasInfo(alias);
|
||||||
|
crls = new HashSet<X509CRL>();
|
||||||
|
if (crlfiles.size() > 0 || autoCRL) {
|
||||||
|
CertificateFactory fac =
|
||||||
|
CertificateFactory.getInstance("X509");
|
||||||
|
List<CRL> list = new ArrayList<CRL>();
|
||||||
|
for (String file: crlfiles) {
|
||||||
|
Collection<? extends CRL> tmp = KeyTool.loadCRLs(file);
|
||||||
|
for (CRL crl: tmp) {
|
||||||
|
if (crl instanceof X509CRL) {
|
||||||
|
crls.add((X509CRL)crl);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (autoCRL) {
|
||||||
|
List<CRL> crlsFromCert =
|
||||||
|
KeyTool.readCRLsFromCert(certChain[0]);
|
||||||
|
for (CRL crl: crlsFromCert) {
|
||||||
|
if (crl instanceof X509CRL) {
|
||||||
|
crls.add((X509CRL)crl);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// load the alternative signing mechanism
|
// load the alternative signing mechanism
|
||||||
if (altSignerClass != null) {
|
if (altSignerClass != null) {
|
||||||
@ -367,6 +396,13 @@ public class JarSigner {
|
|||||||
} else if (collator.compare(flags, "-digestalg") ==0) {
|
} else if (collator.compare(flags, "-digestalg") ==0) {
|
||||||
if (++n == args.length) usageNoArg();
|
if (++n == args.length) usageNoArg();
|
||||||
digestalg = args[n];
|
digestalg = args[n];
|
||||||
|
} else if (collator.compare(flags, "-crl") ==0) {
|
||||||
|
if ("auto".equals(modifier)) {
|
||||||
|
autoCRL = true;
|
||||||
|
} else {
|
||||||
|
if (++n == args.length) usageNoArg();
|
||||||
|
crlfiles.add(args[n]);
|
||||||
|
}
|
||||||
} else if (collator.compare(flags, "-certs") ==0) {
|
} else if (collator.compare(flags, "-certs") ==0) {
|
||||||
showcerts = true;
|
showcerts = true;
|
||||||
} else if (collator.compare(flags, "-strict") ==0) {
|
} else if (collator.compare(flags, "-strict") ==0) {
|
||||||
@ -515,6 +551,9 @@ public class JarSigner {
|
|||||||
System.out.println(rb.getString
|
System.out.println(rb.getString
|
||||||
("[-sigalg <algorithm>] name of signature algorithm"));
|
("[-sigalg <algorithm>] name of signature algorithm"));
|
||||||
System.out.println();
|
System.out.println();
|
||||||
|
System.out.println(rb.getString
|
||||||
|
("[-crl[:auto| <file>] include CRL in signed jar"));
|
||||||
|
System.out.println();
|
||||||
System.out.println(rb.getString
|
System.out.println(rb.getString
|
||||||
("[-verify] verify a signed JAR file"));
|
("[-verify] verify a signed JAR file"));
|
||||||
System.out.println();
|
System.out.println();
|
||||||
@ -654,6 +693,20 @@ public class JarSigner {
|
|||||||
if (showcerts) {
|
if (showcerts) {
|
||||||
sb.append(si);
|
sb.append(si);
|
||||||
sb.append('\n');
|
sb.append('\n');
|
||||||
|
CRL[] crls = SharedSecrets
|
||||||
|
.getJavaSecurityCodeSignerAccess()
|
||||||
|
.getCRLs(signer);
|
||||||
|
if (crls != null) {
|
||||||
|
for (CRL crl: crls) {
|
||||||
|
if (crl instanceof X509CRLImpl) {
|
||||||
|
sb.append(tab).append("[");
|
||||||
|
sb.append(String.format(
|
||||||
|
rb.getString("with a CRL including %d entries"),
|
||||||
|
((X509CRLImpl)crl).getRevokedCertificates().size()))
|
||||||
|
.append("]\n");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else if (showcerts && !verbose.equals("all")) {
|
} else if (showcerts && !verbose.equals("all")) {
|
||||||
@ -1233,7 +1286,7 @@ public class JarSigner {
|
|||||||
|
|
||||||
try {
|
try {
|
||||||
block =
|
block =
|
||||||
sf.generateBlock(privateKey, sigalg, certChain,
|
sf.generateBlock(privateKey, sigalg, certChain, crls,
|
||||||
externalSF, tsaUrl, tsaCert, signingMechanism, args,
|
externalSF, tsaUrl, tsaCert, signingMechanism, args,
|
||||||
zipFile);
|
zipFile);
|
||||||
} catch (SocketTimeoutException e) {
|
} catch (SocketTimeoutException e) {
|
||||||
@ -2197,6 +2250,7 @@ class SignatureFile {
|
|||||||
public Block generateBlock(PrivateKey privateKey,
|
public Block generateBlock(PrivateKey privateKey,
|
||||||
String sigalg,
|
String sigalg,
|
||||||
X509Certificate[] certChain,
|
X509Certificate[] certChain,
|
||||||
|
Set<X509CRL> crls,
|
||||||
boolean externalSF, String tsaUrl,
|
boolean externalSF, String tsaUrl,
|
||||||
X509Certificate tsaCert,
|
X509Certificate tsaCert,
|
||||||
ContentSigner signingMechanism,
|
ContentSigner signingMechanism,
|
||||||
@ -2204,7 +2258,7 @@ class SignatureFile {
|
|||||||
throws NoSuchAlgorithmException, InvalidKeyException, IOException,
|
throws NoSuchAlgorithmException, InvalidKeyException, IOException,
|
||||||
SignatureException, CertificateException
|
SignatureException, CertificateException
|
||||||
{
|
{
|
||||||
return new Block(this, privateKey, sigalg, certChain, externalSF,
|
return new Block(this, privateKey, sigalg, certChain, crls, externalSF,
|
||||||
tsaUrl, tsaCert, signingMechanism, args, zipFile);
|
tsaUrl, tsaCert, signingMechanism, args, zipFile);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2218,7 +2272,8 @@ class SignatureFile {
|
|||||||
* Construct a new signature block.
|
* Construct a new signature block.
|
||||||
*/
|
*/
|
||||||
Block(SignatureFile sfg, PrivateKey privateKey, String sigalg,
|
Block(SignatureFile sfg, PrivateKey privateKey, String sigalg,
|
||||||
X509Certificate[] certChain, boolean externalSF, String tsaUrl,
|
X509Certificate[] certChain, Set<X509CRL> crls,
|
||||||
|
boolean externalSF, String tsaUrl,
|
||||||
X509Certificate tsaCert, ContentSigner signingMechanism,
|
X509Certificate tsaCert, ContentSigner signingMechanism,
|
||||||
String[] args, ZipFile zipFile)
|
String[] args, ZipFile zipFile)
|
||||||
throws NoSuchAlgorithmException, InvalidKeyException, IOException,
|
throws NoSuchAlgorithmException, InvalidKeyException, IOException,
|
||||||
@ -2305,7 +2360,7 @@ class SignatureFile {
|
|||||||
// Assemble parameters for the signing mechanism
|
// Assemble parameters for the signing mechanism
|
||||||
ContentSignerParameters params =
|
ContentSignerParameters params =
|
||||||
new JarSignerParameters(args, tsaUri, tsaCert, signature,
|
new JarSignerParameters(args, tsaUri, tsaCert, signature,
|
||||||
signatureAlgorithm, certChain, content, zipFile);
|
signatureAlgorithm, certChain, crls, content, zipFile);
|
||||||
|
|
||||||
// Generate the signature block
|
// Generate the signature block
|
||||||
block = signingMechanism.generateSignedData(
|
block = signingMechanism.generateSignedData(
|
||||||
@ -2346,6 +2401,7 @@ class JarSignerParameters implements ContentSignerParameters {
|
|||||||
private byte[] signature;
|
private byte[] signature;
|
||||||
private String signatureAlgorithm;
|
private String signatureAlgorithm;
|
||||||
private X509Certificate[] signerCertificateChain;
|
private X509Certificate[] signerCertificateChain;
|
||||||
|
private Set<X509CRL> crls;
|
||||||
private byte[] content;
|
private byte[] content;
|
||||||
private ZipFile source;
|
private ZipFile source;
|
||||||
|
|
||||||
@ -2354,7 +2410,8 @@ class JarSignerParameters implements ContentSignerParameters {
|
|||||||
*/
|
*/
|
||||||
JarSignerParameters(String[] args, URI tsa, X509Certificate tsaCertificate,
|
JarSignerParameters(String[] args, URI tsa, X509Certificate tsaCertificate,
|
||||||
byte[] signature, String signatureAlgorithm,
|
byte[] signature, String signatureAlgorithm,
|
||||||
X509Certificate[] signerCertificateChain, byte[] content,
|
X509Certificate[] signerCertificateChain, Set<X509CRL> crls,
|
||||||
|
byte[] content,
|
||||||
ZipFile source) {
|
ZipFile source) {
|
||||||
|
|
||||||
if (signature == null || signatureAlgorithm == null ||
|
if (signature == null || signatureAlgorithm == null ||
|
||||||
@ -2367,6 +2424,7 @@ class JarSignerParameters implements ContentSignerParameters {
|
|||||||
this.signature = signature;
|
this.signature = signature;
|
||||||
this.signatureAlgorithm = signatureAlgorithm;
|
this.signatureAlgorithm = signatureAlgorithm;
|
||||||
this.signerCertificateChain = signerCertificateChain;
|
this.signerCertificateChain = signerCertificateChain;
|
||||||
|
this.crls = crls;
|
||||||
this.content = content;
|
this.content = content;
|
||||||
this.source = source;
|
this.source = source;
|
||||||
}
|
}
|
||||||
@ -2442,4 +2500,13 @@ class JarSignerParameters implements ContentSignerParameters {
|
|||||||
public ZipFile getSource() {
|
public ZipFile getSource() {
|
||||||
return source;
|
return source;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Set<X509CRL> getCRLs() {
|
||||||
|
if (crls == null) {
|
||||||
|
return Collections.emptySet();
|
||||||
|
} else {
|
||||||
|
return Collections.unmodifiableSet(crls);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright 2000-2009 Sun Microsystems, Inc. All Rights Reserved.
|
* Copyright 2000-2010 Sun Microsystems, Inc. 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
|
||||||
@ -74,6 +74,8 @@ public class JarSignerResources extends java.util.ListResourceBundle {
|
|||||||
"[-digestalg <algorithm>] name of digest algorithm"},
|
"[-digestalg <algorithm>] name of digest algorithm"},
|
||||||
{"[-sigalg <algorithm>] name of signature algorithm",
|
{"[-sigalg <algorithm>] name of signature algorithm",
|
||||||
"[-sigalg <algorithm>] name of signature algorithm"},
|
"[-sigalg <algorithm>] name of signature algorithm"},
|
||||||
|
{"[-crl[:auto| <file>] include CRL in signed jar",
|
||||||
|
"[-crl[:auto| <file>] include CRL in signed jar"},
|
||||||
{"[-verify] verify a signed JAR file",
|
{"[-verify] verify a signed JAR file",
|
||||||
"[-verify] verify a signed JAR file"},
|
"[-verify] verify a signed JAR file"},
|
||||||
{"[-verbose[:suboptions]] verbose output when signing/verifying.",
|
{"[-verbose[:suboptions]] verbose output when signing/verifying.",
|
||||||
@ -191,6 +193,7 @@ public class JarSignerResources extends java.util.ListResourceBundle {
|
|||||||
{"using an alternative signing mechanism",
|
{"using an alternative signing mechanism",
|
||||||
"using an alternative signing mechanism"},
|
"using an alternative signing mechanism"},
|
||||||
{"entry was signed on", "entry was signed on {0}"},
|
{"entry was signed on", "entry was signed on {0}"},
|
||||||
|
{"with a CRL including %d entries", "with a CRL including %d entries"},
|
||||||
{"Warning: ", "Warning: "},
|
{"Warning: ", "Warning: "},
|
||||||
{"This jar contains unsigned entries which have not been integrity-checked. ",
|
{"This jar contains unsigned entries which have not been integrity-checked. ",
|
||||||
"This jar contains unsigned entries which have not been integrity-checked. "},
|
"This jar contains unsigned entries which have not been integrity-checked. "},
|
||||||
|
@ -25,6 +25,7 @@
|
|||||||
|
|
||||||
package sun.security.tools;
|
package sun.security.tools;
|
||||||
|
|
||||||
|
import sun.misc.SharedSecrets;
|
||||||
import java.io.*;
|
import java.io.*;
|
||||||
import java.security.CodeSigner;
|
import java.security.CodeSigner;
|
||||||
import java.security.KeyStore;
|
import java.security.KeyStore;
|
||||||
@ -42,6 +43,7 @@ import java.security.Principal;
|
|||||||
import java.security.Provider;
|
import java.security.Provider;
|
||||||
import java.security.cert.Certificate;
|
import java.security.cert.Certificate;
|
||||||
import java.security.cert.CertificateFactory;
|
import java.security.cert.CertificateFactory;
|
||||||
|
import java.security.cert.CRL;
|
||||||
import java.security.cert.X509Certificate;
|
import java.security.cert.X509Certificate;
|
||||||
import java.security.cert.CertificateException;
|
import java.security.cert.CertificateException;
|
||||||
import java.text.Collator;
|
import java.text.Collator;
|
||||||
@ -50,14 +52,20 @@ import java.util.*;
|
|||||||
import java.util.jar.JarEntry;
|
import java.util.jar.JarEntry;
|
||||||
import java.util.jar.JarFile;
|
import java.util.jar.JarFile;
|
||||||
import java.lang.reflect.Constructor;
|
import java.lang.reflect.Constructor;
|
||||||
|
import java.math.BigInteger;
|
||||||
|
import java.net.URI;
|
||||||
import java.net.URL;
|
import java.net.URL;
|
||||||
import java.net.URLClassLoader;
|
import java.net.URLClassLoader;
|
||||||
|
import java.security.cert.CertStore;
|
||||||
|
|
||||||
|
import java.security.cert.X509CRL;
|
||||||
|
import java.security.cert.X509CRLEntry;
|
||||||
|
import java.security.cert.X509CRLSelector;
|
||||||
|
import javax.security.auth.x500.X500Principal;
|
||||||
import sun.misc.BASE64Encoder;
|
import sun.misc.BASE64Encoder;
|
||||||
import sun.security.util.ObjectIdentifier;
|
import sun.security.util.ObjectIdentifier;
|
||||||
import sun.security.pkcs.PKCS10;
|
import sun.security.pkcs.PKCS10;
|
||||||
import sun.security.provider.X509Factory;
|
import sun.security.provider.X509Factory;
|
||||||
import sun.security.util.DerOutputStream;
|
|
||||||
import sun.security.util.Password;
|
import sun.security.util.Password;
|
||||||
import sun.security.util.PathList;
|
import sun.security.util.PathList;
|
||||||
import javax.crypto.KeyGenerator;
|
import javax.crypto.KeyGenerator;
|
||||||
@ -72,6 +80,7 @@ import javax.net.ssl.X509TrustManager;
|
|||||||
import sun.misc.BASE64Decoder;
|
import sun.misc.BASE64Decoder;
|
||||||
import sun.security.pkcs.PKCS10Attribute;
|
import sun.security.pkcs.PKCS10Attribute;
|
||||||
import sun.security.pkcs.PKCS9Attribute;
|
import sun.security.pkcs.PKCS9Attribute;
|
||||||
|
import sun.security.provider.certpath.ldap.LDAPCertStoreHelper;
|
||||||
import sun.security.util.DerValue;
|
import sun.security.util.DerValue;
|
||||||
import sun.security.x509.*;
|
import sun.security.x509.*;
|
||||||
|
|
||||||
@ -147,6 +156,7 @@ public final class KeyTool {
|
|||||||
private Set<char[]> passwords = new HashSet<char[]> ();
|
private Set<char[]> passwords = new HashSet<char[]> ();
|
||||||
private String startDate = null;
|
private String startDate = null;
|
||||||
|
|
||||||
|
private List <String> ids = new ArrayList <String> (); // used in GENCRL
|
||||||
private List <String> v3ext = new ArrayList <String> ();
|
private List <String> v3ext = new ArrayList <String> ();
|
||||||
|
|
||||||
enum Command {
|
enum Command {
|
||||||
@ -180,9 +190,6 @@ public final class KeyTool {
|
|||||||
STARTDATE, EXT, VALIDITY, KEYPASS, KEYSTORE,
|
STARTDATE, EXT, VALIDITY, KEYPASS, KEYSTORE,
|
||||||
STOREPASS, STORETYPE, PROVIDERNAME, PROVIDERCLASS,
|
STOREPASS, STORETYPE, PROVIDERNAME, PROVIDERCLASS,
|
||||||
PROVIDERARG, PROVIDERPATH, V, PROTECTED),
|
PROVIDERARG, PROVIDERPATH, V, PROTECTED),
|
||||||
IDENTITYDB("Imports entries from a JDK 1.1.x-style identity database",
|
|
||||||
FILEIN, STORETYPE, KEYSTORE, STOREPASS, PROVIDERNAME,
|
|
||||||
PROVIDERCLASS, PROVIDERARG, PROVIDERPATH, V),
|
|
||||||
IMPORTCERT("Imports a certificate or a certificate chain",
|
IMPORTCERT("Imports a certificate or a certificate chain",
|
||||||
NOPROMPT, TRUSTCACERTS, PROTECTED, ALIAS, FILEIN,
|
NOPROMPT, TRUSTCACERTS, PROTECTED, ALIAS, FILEIN,
|
||||||
KEYPASS, KEYSTORE, STOREPASS, STORETYPE,
|
KEYPASS, KEYSTORE, STOREPASS, STORETYPE,
|
||||||
@ -195,10 +202,6 @@ public final class KeyTool {
|
|||||||
SRCALIAS, DESTALIAS, SRCKEYPASS, DESTKEYPASS,
|
SRCALIAS, DESTALIAS, SRCKEYPASS, DESTKEYPASS,
|
||||||
NOPROMPT, PROVIDERCLASS, PROVIDERARG, PROVIDERPATH,
|
NOPROMPT, PROVIDERCLASS, PROVIDERARG, PROVIDERPATH,
|
||||||
V),
|
V),
|
||||||
KEYCLONE("Clones a key entry",
|
|
||||||
ALIAS, DESTALIAS, KEYPASS, NEW, STORETYPE,
|
|
||||||
KEYSTORE, STOREPASS, PROVIDERNAME, PROVIDERCLASS,
|
|
||||||
PROVIDERARG, PROVIDERPATH, V),
|
|
||||||
KEYPASSWD("Changes the key password of an entry",
|
KEYPASSWD("Changes the key password of an entry",
|
||||||
ALIAS, KEYPASS, NEW, KEYSTORE, STOREPASS,
|
ALIAS, KEYPASS, NEW, KEYSTORE, STOREPASS,
|
||||||
STORETYPE, PROVIDERNAME, PROVIDERCLASS, PROVIDERARG,
|
STORETYPE, PROVIDERNAME, PROVIDERCLASS, PROVIDERARG,
|
||||||
@ -211,12 +214,29 @@ public final class KeyTool {
|
|||||||
RFC, FILEIN, SSLSERVER, JARFILE, V),
|
RFC, FILEIN, SSLSERVER, JARFILE, V),
|
||||||
PRINTCERTREQ("Prints the content of a certificate request",
|
PRINTCERTREQ("Prints the content of a certificate request",
|
||||||
FILEIN, V),
|
FILEIN, V),
|
||||||
|
PRINTCRL("Prints the content of a CRL file",
|
||||||
|
FILEIN, V),
|
||||||
|
STOREPASSWD("Changes the store password of a keystore",
|
||||||
|
NEW, KEYSTORE, STOREPASS, STORETYPE, PROVIDERNAME,
|
||||||
|
PROVIDERCLASS, PROVIDERARG, PROVIDERPATH, V),
|
||||||
|
|
||||||
|
// Undocumented start here, KEYCLONE is used a marker in -help;
|
||||||
|
|
||||||
|
KEYCLONE("Clones a key entry",
|
||||||
|
ALIAS, DESTALIAS, KEYPASS, NEW, STORETYPE,
|
||||||
|
KEYSTORE, STOREPASS, PROVIDERNAME, PROVIDERCLASS,
|
||||||
|
PROVIDERARG, PROVIDERPATH, V),
|
||||||
SELFCERT("Generates a self-signed certificate",
|
SELFCERT("Generates a self-signed certificate",
|
||||||
ALIAS, SIGALG, DNAME, STARTDATE, VALIDITY, KEYPASS,
|
ALIAS, SIGALG, DNAME, STARTDATE, VALIDITY, KEYPASS,
|
||||||
STORETYPE, KEYSTORE, STOREPASS, PROVIDERNAME,
|
STORETYPE, KEYSTORE, STOREPASS, PROVIDERNAME,
|
||||||
PROVIDERCLASS, PROVIDERARG, PROVIDERPATH, V),
|
PROVIDERCLASS, PROVIDERARG, PROVIDERPATH, V),
|
||||||
STOREPASSWD("Changes the store password of a keystore",
|
GENCRL("Generates CRL",
|
||||||
NEW, KEYSTORE, STOREPASS, STORETYPE, PROVIDERNAME,
|
RFC, FILEOUT, ID,
|
||||||
|
ALIAS, SIGALG, EXT, KEYPASS, KEYSTORE,
|
||||||
|
STOREPASS, STORETYPE, PROVIDERNAME, PROVIDERCLASS,
|
||||||
|
PROVIDERARG, PROVIDERPATH, V, PROTECTED),
|
||||||
|
IDENTITYDB("Imports entries from a JDK 1.1.x-style identity database",
|
||||||
|
FILEIN, STORETYPE, KEYSTORE, STOREPASS, PROVIDERNAME,
|
||||||
PROVIDERCLASS, PROVIDERARG, PROVIDERPATH, V);
|
PROVIDERCLASS, PROVIDERARG, PROVIDERPATH, V);
|
||||||
|
|
||||||
final String description;
|
final String description;
|
||||||
@ -244,6 +264,7 @@ public final class KeyTool {
|
|||||||
EXT("ext", "<value>", "X.509 extension"),
|
EXT("ext", "<value>", "X.509 extension"),
|
||||||
FILEOUT("file", "<filename>", "output file name"),
|
FILEOUT("file", "<filename>", "output file name"),
|
||||||
FILEIN("file", "<filename>", "input file name"),
|
FILEIN("file", "<filename>", "input file name"),
|
||||||
|
ID("id", "<id:reason>", "Serial ID of cert to revoke"),
|
||||||
INFILE("infile", "<filename>", "input file name"),
|
INFILE("infile", "<filename>", "input file name"),
|
||||||
KEYALG("keyalg", "<keyalg>", "key algorithm name"),
|
KEYALG("keyalg", "<keyalg>", "key algorithm name"),
|
||||||
KEYPASS("keypass", "<arg>", "key password"),
|
KEYPASS("keypass", "<arg>", "key password"),
|
||||||
@ -458,6 +479,8 @@ public final class KeyTool {
|
|||||||
validity = Long.parseLong(args[++i]);
|
validity = Long.parseLong(args[++i]);
|
||||||
} else if (collator.compare(flags, "-ext") == 0) {
|
} else if (collator.compare(flags, "-ext") == 0) {
|
||||||
v3ext.add(args[++i]);
|
v3ext.add(args[++i]);
|
||||||
|
} else if (collator.compare(flags, "-id") == 0) {
|
||||||
|
ids.add(args[++i]);
|
||||||
} else if (collator.compare(flags, "-file") == 0) {
|
} else if (collator.compare(flags, "-file") == 0) {
|
||||||
filename = args[++i];
|
filename = args[++i];
|
||||||
} else if (collator.compare(flags, "-infile") == 0) {
|
} else if (collator.compare(flags, "-infile") == 0) {
|
||||||
@ -720,7 +743,8 @@ public final class KeyTool {
|
|||||||
command != GENSECKEY &&
|
command != GENSECKEY &&
|
||||||
command != IDENTITYDB &&
|
command != IDENTITYDB &&
|
||||||
command != IMPORTCERT &&
|
command != IMPORTCERT &&
|
||||||
command != IMPORTKEYSTORE) {
|
command != IMPORTKEYSTORE &&
|
||||||
|
command != PRINTCRL) {
|
||||||
throw new Exception(rb.getString
|
throw new Exception(rb.getString
|
||||||
("Keystore file does not exist: ") + ksfname);
|
("Keystore file does not exist: ") + ksfname);
|
||||||
}
|
}
|
||||||
@ -855,11 +879,13 @@ public final class KeyTool {
|
|||||||
&& !KeyStoreUtil.isWindowsKeyStore(storetype)
|
&& !KeyStoreUtil.isWindowsKeyStore(storetype)
|
||||||
&& isKeyStoreRelated(command)) {
|
&& isKeyStoreRelated(command)) {
|
||||||
// here we have EXPORTCERT and LIST (info valid until STOREPASSWD)
|
// here we have EXPORTCERT and LIST (info valid until STOREPASSWD)
|
||||||
|
if (command != PRINTCRL) {
|
||||||
System.err.print(rb.getString("Enter keystore password: "));
|
System.err.print(rb.getString("Enter keystore password: "));
|
||||||
System.err.flush();
|
System.err.flush();
|
||||||
storePass = Password.readPassword(System.in);
|
storePass = Password.readPassword(System.in);
|
||||||
passwords.add(storePass);
|
passwords.add(storePass);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Now load a nullStream-based keystore,
|
// Now load a nullStream-based keystore,
|
||||||
// or verify the integrity of an input stream-based keystore
|
// or verify the integrity of an input stream-based keystore
|
||||||
@ -895,7 +921,7 @@ public final class KeyTool {
|
|||||||
|
|
||||||
// Create a certificate factory
|
// Create a certificate factory
|
||||||
if (command == PRINTCERT || command == IMPORTCERT
|
if (command == PRINTCERT || command == IMPORTCERT
|
||||||
|| command == IDENTITYDB) {
|
|| command == IDENTITYDB || command == PRINTCRL) {
|
||||||
cf = CertificateFactory.getInstance("X509");
|
cf = CertificateFactory.getInstance("X509");
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1086,6 +1112,22 @@ public final class KeyTool {
|
|||||||
ps.close();
|
ps.close();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
} else if (command == GENCRL) {
|
||||||
|
if (alias == null) {
|
||||||
|
alias = keyAlias;
|
||||||
|
}
|
||||||
|
PrintStream ps = null;
|
||||||
|
if (filename != null) {
|
||||||
|
ps = new PrintStream(new FileOutputStream(filename));
|
||||||
|
out = ps;
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
doGenCRL(out);
|
||||||
|
} finally {
|
||||||
|
if (ps != null) {
|
||||||
|
ps.close();
|
||||||
|
}
|
||||||
|
}
|
||||||
} else if (command == PRINTCERTREQ) {
|
} else if (command == PRINTCERTREQ) {
|
||||||
InputStream inStream = System.in;
|
InputStream inStream = System.in;
|
||||||
if (filename != null) {
|
if (filename != null) {
|
||||||
@ -1098,6 +1140,8 @@ public final class KeyTool {
|
|||||||
inStream.close();
|
inStream.close();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
} else if (command == PRINTCRL) {
|
||||||
|
doPrintCRL(filename, out);
|
||||||
}
|
}
|
||||||
|
|
||||||
// If we need to save the keystore, do so.
|
// If we need to save the keystore, do so.
|
||||||
@ -1152,7 +1196,8 @@ public final class KeyTool {
|
|||||||
CertificateValidity interval = new CertificateValidity(firstDate,
|
CertificateValidity interval = new CertificateValidity(firstDate,
|
||||||
lastDate);
|
lastDate);
|
||||||
|
|
||||||
PrivateKey privateKey = (PrivateKey)recoverKey(alias, storePass, keyPass).fst;
|
PrivateKey privateKey =
|
||||||
|
(PrivateKey)recoverKey(alias, storePass, keyPass).fst;
|
||||||
if (sigAlgName == null) {
|
if (sigAlgName == null) {
|
||||||
sigAlgName = getCompatibleSigAlgName(privateKey.getAlgorithm());
|
sigAlgName = getCompatibleSigAlgName(privateKey.getAlgorithm());
|
||||||
}
|
}
|
||||||
@ -1221,6 +1266,56 @@ public final class KeyTool {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void doGenCRL(PrintStream out)
|
||||||
|
throws Exception {
|
||||||
|
if (ids == null) {
|
||||||
|
throw new Exception("Must provide -id when -gencrl");
|
||||||
|
}
|
||||||
|
Certificate signerCert = keyStore.getCertificate(alias);
|
||||||
|
byte[] encoded = signerCert.getEncoded();
|
||||||
|
X509CertImpl signerCertImpl = new X509CertImpl(encoded);
|
||||||
|
X509CertInfo signerCertInfo = (X509CertInfo)signerCertImpl.get(
|
||||||
|
X509CertImpl.NAME + "." + X509CertImpl.INFO);
|
||||||
|
X500Name owner = (X500Name)signerCertInfo.get(X509CertInfo.SUBJECT + "." +
|
||||||
|
CertificateSubjectName.DN_NAME);
|
||||||
|
|
||||||
|
Date firstDate = getStartDate(startDate);
|
||||||
|
Date lastDate = (Date) firstDate.clone();
|
||||||
|
lastDate.setTime(lastDate.getTime() + (long)validity*1000*24*60*60);
|
||||||
|
CertificateValidity interval = new CertificateValidity(firstDate,
|
||||||
|
lastDate);
|
||||||
|
|
||||||
|
|
||||||
|
PrivateKey privateKey =
|
||||||
|
(PrivateKey)recoverKey(alias, storePass, keyPass).fst;
|
||||||
|
if (sigAlgName == null) {
|
||||||
|
sigAlgName = getCompatibleSigAlgName(privateKey.getAlgorithm());
|
||||||
|
}
|
||||||
|
|
||||||
|
X509CRLEntry[] badCerts = new X509CRLEntry[ids.size()];
|
||||||
|
for (int i=0; i<ids.size(); i++) {
|
||||||
|
String id = ids.get(i);
|
||||||
|
int d = id.indexOf(':');
|
||||||
|
if (d >= 0) {
|
||||||
|
CRLExtensions ext = new CRLExtensions();
|
||||||
|
ext.set("Reason", new CRLReasonCodeExtension(Integer.parseInt(id.substring(d+1))));
|
||||||
|
badCerts[i] = new X509CRLEntryImpl(new BigInteger(id.substring(0, d)),
|
||||||
|
firstDate, ext);
|
||||||
|
} else {
|
||||||
|
badCerts[i] = new X509CRLEntryImpl(new BigInteger(ids.get(i)), firstDate);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
X509CRLImpl crl = new X509CRLImpl(owner, firstDate, lastDate, badCerts);
|
||||||
|
crl.sign(privateKey, sigAlgName);
|
||||||
|
if (rfc) {
|
||||||
|
out.println("-----BEGIN X509 CRL-----");
|
||||||
|
new BASE64Encoder().encodeBuffer(crl.getEncodedInternal(), out);
|
||||||
|
out.println("-----END X509 CRL-----");
|
||||||
|
} else {
|
||||||
|
out.write(crl.getEncodedInternal());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Creates a PKCS#10 cert signing request, corresponding to the
|
* Creates a PKCS#10 cert signing request, corresponding to the
|
||||||
* keys (and name) associated with a given alias.
|
* keys (and name) associated with a given alias.
|
||||||
@ -1925,6 +2020,177 @@ public final class KeyTool {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static <T> Iterable<T> e2i(final Enumeration<T> e) {
|
||||||
|
return new Iterable<T>() {
|
||||||
|
@Override
|
||||||
|
public Iterator<T> iterator() {
|
||||||
|
return new Iterator<T>() {
|
||||||
|
@Override
|
||||||
|
public boolean hasNext() {
|
||||||
|
return e.hasMoreElements();
|
||||||
|
}
|
||||||
|
@Override
|
||||||
|
public T next() {
|
||||||
|
return e.nextElement();
|
||||||
|
}
|
||||||
|
public void remove() {
|
||||||
|
throw new UnsupportedOperationException("Not supported yet.");
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Loads CRLs from a source. This method is also called in JarSigner.
|
||||||
|
* @param src the source, which means System.in if null, or a URI,
|
||||||
|
* or a bare file path name
|
||||||
|
*/
|
||||||
|
public static Collection<? extends CRL> loadCRLs(String src) throws Exception {
|
||||||
|
InputStream in = null;
|
||||||
|
URI uri = null;
|
||||||
|
if (src == null) {
|
||||||
|
in = System.in;
|
||||||
|
} else {
|
||||||
|
try {
|
||||||
|
uri = new URI(src);
|
||||||
|
if (uri.getScheme().equals("ldap")) {
|
||||||
|
// No input stream for LDAP
|
||||||
|
} else {
|
||||||
|
in = uri.toURL().openStream();
|
||||||
|
}
|
||||||
|
} catch (Exception e) {
|
||||||
|
try {
|
||||||
|
in = new FileInputStream(src);
|
||||||
|
} catch (Exception e2) {
|
||||||
|
if (uri == null || uri.getScheme() == null) {
|
||||||
|
throw e2; // More likely a bare file path
|
||||||
|
} else {
|
||||||
|
throw e; // More likely a protocol or network problem
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (in != null) {
|
||||||
|
try {
|
||||||
|
// Read the full stream before feeding to X509Factory,
|
||||||
|
// otherwise, keytool -gencrl | keytool -printcrl
|
||||||
|
// might not work properly, since -gencrl is slow
|
||||||
|
// and there's no data in the pipe at the beginning.
|
||||||
|
ByteArrayOutputStream bout = new ByteArrayOutputStream();
|
||||||
|
byte[] b = new byte[4096];
|
||||||
|
while (true) {
|
||||||
|
int len = in.read(b);
|
||||||
|
if (len < 0) break;
|
||||||
|
bout.write(b, 0, len);
|
||||||
|
}
|
||||||
|
return CertificateFactory.getInstance("X509").generateCRLs(
|
||||||
|
new ByteArrayInputStream(bout.toByteArray()));
|
||||||
|
} finally {
|
||||||
|
if (in != System.in) {
|
||||||
|
in.close();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else { // must be LDAP, and uri is not null
|
||||||
|
String path = uri.getPath();
|
||||||
|
if (path.charAt(0) == '/') path = path.substring(1);
|
||||||
|
LDAPCertStoreHelper h = new LDAPCertStoreHelper();
|
||||||
|
CertStore s = h.getCertStore(uri);
|
||||||
|
X509CRLSelector sel =
|
||||||
|
h.wrap(new X509CRLSelector(), null, path);
|
||||||
|
return s.getCRLs(sel);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns CRLs described in a X509Certificate's CRLDistributionPoints
|
||||||
|
* Extension. Only those containing a general name of type URI are read.
|
||||||
|
*/
|
||||||
|
public static List<CRL> readCRLsFromCert(X509Certificate cert)
|
||||||
|
throws Exception {
|
||||||
|
List<CRL> crls = new ArrayList<CRL>();
|
||||||
|
CRLDistributionPointsExtension ext =
|
||||||
|
X509CertImpl.toImpl(cert).getCRLDistributionPointsExtension();
|
||||||
|
if (ext == null) return crls;
|
||||||
|
for (DistributionPoint o: (List<DistributionPoint>)
|
||||||
|
ext.get(CRLDistributionPointsExtension.POINTS)) {
|
||||||
|
GeneralNames names = o.getFullName();
|
||||||
|
if (names != null) {
|
||||||
|
for (GeneralName name: names.names()) {
|
||||||
|
if (name.getType() == GeneralNameInterface.NAME_URI) {
|
||||||
|
URIName uriName = (URIName)name.getName();
|
||||||
|
for (CRL crl: KeyTool.loadCRLs(uriName.getName())) {
|
||||||
|
if (crl instanceof X509CRL) {
|
||||||
|
crls.add((X509CRL)crl);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break; // Different name should point to same CRL
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return crls;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static String verifyCRL(KeyStore ks, CRL crl)
|
||||||
|
throws Exception {
|
||||||
|
X509CRLImpl xcrl = (X509CRLImpl)crl;
|
||||||
|
X500Principal issuer = xcrl.getIssuerX500Principal();
|
||||||
|
for (String s: e2i(ks.aliases())) {
|
||||||
|
Certificate cert = ks.getCertificate(s);
|
||||||
|
if (cert instanceof X509Certificate) {
|
||||||
|
X509Certificate xcert = (X509Certificate)cert;
|
||||||
|
if (xcert.getSubjectX500Principal().equals(issuer)) {
|
||||||
|
try {
|
||||||
|
((X509CRLImpl)crl).verify(cert.getPublicKey());
|
||||||
|
return s;
|
||||||
|
} catch (Exception e) {
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void doPrintCRL(String src, PrintStream out)
|
||||||
|
throws Exception {
|
||||||
|
for (CRL crl: loadCRLs(src)) {
|
||||||
|
printCRL(crl, out);
|
||||||
|
String issuer = null;
|
||||||
|
if (caks != null) {
|
||||||
|
issuer = verifyCRL(caks, crl);
|
||||||
|
if (issuer != null) {
|
||||||
|
System.out.println("Verified by " + issuer + " in cacerts");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (issuer == null && keyStore != null) {
|
||||||
|
issuer = verifyCRL(keyStore, crl);
|
||||||
|
if (issuer != null) {
|
||||||
|
System.out.println("Verified by " + issuer + " in keystore");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (issuer == null) {
|
||||||
|
out.println(rb.getString
|
||||||
|
("*******************************************"));
|
||||||
|
out.println("WARNING: not verified. Make sure -keystore and -alias are correct.");
|
||||||
|
out.println(rb.getString
|
||||||
|
("*******************************************\n\n"));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void printCRL(CRL crl, PrintStream out)
|
||||||
|
throws Exception {
|
||||||
|
if (rfc) {
|
||||||
|
X509CRL xcrl = (X509CRL)crl;
|
||||||
|
out.println("-----BEGIN X509 CRL-----");
|
||||||
|
new BASE64Encoder().encodeBuffer(xcrl.getEncoded(), out);
|
||||||
|
out.println("-----END X509 CRL-----");
|
||||||
|
} else {
|
||||||
|
out.println(crl.toString());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private void doPrintCertReq(InputStream in, PrintStream out)
|
private void doPrintCertReq(InputStream in, PrintStream out)
|
||||||
throws Exception {
|
throws Exception {
|
||||||
|
|
||||||
@ -2063,6 +2329,16 @@ public final class KeyTool {
|
|||||||
out.println();
|
out.println();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
CRL[] crls = SharedSecrets
|
||||||
|
.getJavaSecurityCodeSignerAccess()
|
||||||
|
.getCRLs(signer);
|
||||||
|
if (crls != null) {
|
||||||
|
out.println(rb.getString("CRLs:"));
|
||||||
|
out.println();
|
||||||
|
for (CRL crl: crls) {
|
||||||
|
printCRL(crl, out);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -3330,15 +3606,22 @@ public final class KeyTool {
|
|||||||
/**
|
/**
|
||||||
* Match a command (may be abbreviated) with a command set.
|
* Match a command (may be abbreviated) with a command set.
|
||||||
* @param s the command provided
|
* @param s the command provided
|
||||||
* @param list the legal command set
|
* @param list the legal command set. If there is a null, commands after it
|
||||||
|
* are regarded experimental, which means they are supported but their
|
||||||
|
* existence should not be revealed to user.
|
||||||
* @return the position of a single match, or -1 if none matched
|
* @return the position of a single match, or -1 if none matched
|
||||||
* @throws Exception if s is ambiguous
|
* @throws Exception if s is ambiguous
|
||||||
*/
|
*/
|
||||||
private static int oneOf(String s, String... list) throws Exception {
|
private static int oneOf(String s, String... list) throws Exception {
|
||||||
int[] match = new int[list.length];
|
int[] match = new int[list.length];
|
||||||
int nmatch = 0;
|
int nmatch = 0;
|
||||||
|
int experiment = Integer.MAX_VALUE;
|
||||||
for (int i = 0; i<list.length; i++) {
|
for (int i = 0; i<list.length; i++) {
|
||||||
String one = list[i];
|
String one = list[i];
|
||||||
|
if (one == null) {
|
||||||
|
experiment = i;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
if (one.toLowerCase(Locale.ENGLISH)
|
if (one.toLowerCase(Locale.ENGLISH)
|
||||||
.startsWith(s.toLowerCase(Locale.ENGLISH))) {
|
.startsWith(s.toLowerCase(Locale.ENGLISH))) {
|
||||||
match[nmatch++] = i;
|
match[nmatch++] = i;
|
||||||
@ -3360,18 +3643,28 @@ public final class KeyTool {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (nmatch == 0) return -1;
|
if (nmatch == 0) {
|
||||||
if (nmatch == 1) return match[0];
|
return -1;
|
||||||
|
} else if (nmatch == 1) {
|
||||||
|
return match[0];
|
||||||
|
} else {
|
||||||
|
// If multiple matches is in experimental commands, ignore them
|
||||||
|
if (match[1] > experiment) {
|
||||||
|
return match[0];
|
||||||
|
}
|
||||||
StringBuffer sb = new StringBuffer();
|
StringBuffer sb = new StringBuffer();
|
||||||
MessageFormat form = new MessageFormat(rb.getString
|
MessageFormat form = new MessageFormat(rb.getString
|
||||||
("command {0} is ambiguous:"));
|
("command {0} is ambiguous:"));
|
||||||
Object[] source = {s};
|
Object[] source = {s};
|
||||||
sb.append(form.format(source) +"\n ");
|
sb.append(form.format(source));
|
||||||
for (int i=0; i<nmatch; i++) {
|
sb.append("\n ");
|
||||||
sb.append(" " + list[match[i]]);
|
for (int i=0; i<nmatch && match[i]<experiment; i++) {
|
||||||
|
sb.append(' ');
|
||||||
|
sb.append(list[match[i]]);
|
||||||
}
|
}
|
||||||
throw new Exception(sb.toString());
|
throw new Exception(sb.toString());
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Create a GeneralName object from known types
|
* Create a GeneralName object from known types
|
||||||
@ -3405,6 +3698,8 @@ public final class KeyTool {
|
|||||||
"IssuerAlternativeName",
|
"IssuerAlternativeName",
|
||||||
"SubjectInfoAccess",
|
"SubjectInfoAccess",
|
||||||
"AuthorityInfoAccess",
|
"AuthorityInfoAccess",
|
||||||
|
null,
|
||||||
|
"CRLDistributionPoints",
|
||||||
};
|
};
|
||||||
|
|
||||||
private ObjectIdentifier findOidForExtName(String type)
|
private ObjectIdentifier findOidForExtName(String type)
|
||||||
@ -3417,6 +3712,7 @@ public final class KeyTool {
|
|||||||
case 4: return PKIXExtensions.IssuerAlternativeName_Id;
|
case 4: return PKIXExtensions.IssuerAlternativeName_Id;
|
||||||
case 5: return PKIXExtensions.SubjectInfoAccess_Id;
|
case 5: return PKIXExtensions.SubjectInfoAccess_Id;
|
||||||
case 6: return PKIXExtensions.AuthInfoAccess_Id;
|
case 6: return PKIXExtensions.AuthInfoAccess_Id;
|
||||||
|
case 8: return PKIXExtensions.CRLDistributionPoints_Id;
|
||||||
default: return new ObjectIdentifier(type);
|
default: return new ObjectIdentifier(type);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -3712,6 +4008,28 @@ public final class KeyTool {
|
|||||||
("Illegal value: ") + extstr);
|
("Illegal value: ") + extstr);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
case 8: // CRL, experimental, only support 1 distributionpoint
|
||||||
|
if(value != null) {
|
||||||
|
String[] ps = value.split(",");
|
||||||
|
GeneralNames gnames = new GeneralNames();
|
||||||
|
for(String item: ps) {
|
||||||
|
colonpos = item.indexOf(':');
|
||||||
|
if (colonpos < 0) {
|
||||||
|
throw new Exception("Illegal item " + item + " in " + extstr);
|
||||||
|
}
|
||||||
|
String t = item.substring(0, colonpos);
|
||||||
|
String v = item.substring(colonpos+1);
|
||||||
|
gnames.add(createGeneralName(t, v));
|
||||||
|
}
|
||||||
|
ext.set(CRLDistributionPointsExtension.NAME,
|
||||||
|
new CRLDistributionPointsExtension(
|
||||||
|
isCritical, Collections.singletonList(
|
||||||
|
new DistributionPoint(gnames, null, null))));
|
||||||
|
} else {
|
||||||
|
throw new Exception(rb.getString
|
||||||
|
("Illegal value: ") + extstr);
|
||||||
|
}
|
||||||
|
break;
|
||||||
case -1:
|
case -1:
|
||||||
ObjectIdentifier oid = new ObjectIdentifier(name);
|
ObjectIdentifier oid = new ObjectIdentifier(name);
|
||||||
byte[] data = null;
|
byte[] data = null;
|
||||||
@ -3748,6 +4066,9 @@ public final class KeyTool {
|
|||||||
new DerValue(DerValue.tag_OctetString, data)
|
new DerValue(DerValue.tag_OctetString, data)
|
||||||
.toByteArray()));
|
.toByteArray()));
|
||||||
break;
|
break;
|
||||||
|
default:
|
||||||
|
throw new Exception(rb.getString(
|
||||||
|
"Unknown extension type: ") + extstr);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// always non-critical
|
// always non-critical
|
||||||
@ -3810,12 +4131,9 @@ public final class KeyTool {
|
|||||||
System.err.println(rb.getString("Commands:"));
|
System.err.println(rb.getString("Commands:"));
|
||||||
System.err.println();
|
System.err.println();
|
||||||
for (Command c: Command.values()) {
|
for (Command c: Command.values()) {
|
||||||
if (c != IDENTITYDB
|
if (c == KEYCLONE) break;
|
||||||
&& c != KEYCLONE
|
|
||||||
&& c != SELFCERT) { // Deprecated commands
|
|
||||||
System.err.printf(" %-20s%s\n", c, rb.getString(c.description));
|
System.err.printf(" %-20s%s\n", c, rb.getString(c.description));
|
||||||
}
|
}
|
||||||
}
|
|
||||||
System.err.println();
|
System.err.println();
|
||||||
System.err.println(rb.getString(
|
System.err.println(rb.getString(
|
||||||
"Use \"keytool -command_name -help\" for usage of command_name"));
|
"Use \"keytool -command_name -help\" for usage of command_name"));
|
||||||
|
@ -38,6 +38,7 @@ import java.security.cert.X509Certificate;
|
|||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
import com.sun.jarsigner.*;
|
import com.sun.jarsigner.*;
|
||||||
|
import java.security.cert.X509CRL;
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
import sun.security.pkcs.*;
|
import sun.security.pkcs.*;
|
||||||
import sun.security.timestamp.*;
|
import sun.security.timestamp.*;
|
||||||
@ -239,7 +240,7 @@ public final class TimestampedSigner extends ContentSigner {
|
|||||||
// Create the PKCS #7 signed data message
|
// Create the PKCS #7 signed data message
|
||||||
PKCS7 p7 =
|
PKCS7 p7 =
|
||||||
new PKCS7(algorithms, contentInfo, signerCertificateChain,
|
new PKCS7(algorithms, contentInfo, signerCertificateChain,
|
||||||
signerInfos);
|
parameters.getCRLs().toArray(new X509CRL[parameters.getCRLs().size()]), signerInfos);
|
||||||
ByteArrayOutputStream p7out = new ByteArrayOutputStream();
|
ByteArrayOutputStream p7out = new ByteArrayOutputStream();
|
||||||
p7.encodeSignedData(p7out);
|
p7.encodeSignedData(p7out);
|
||||||
|
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright 2000-2009 Sun Microsystems, Inc. All Rights Reserved.
|
* Copyright 2000-2010 Sun Microsystems, Inc. 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
|
||||||
@ -71,6 +71,7 @@ public class Resources extends java.util.ListResourceBundle {
|
|||||||
"Generates a secret key"}, //-genseckey
|
"Generates a secret key"}, //-genseckey
|
||||||
{"Generates certificate from a certificate request",
|
{"Generates certificate from a certificate request",
|
||||||
"Generates certificate from a certificate request"}, //-gencert
|
"Generates certificate from a certificate request"}, //-gencert
|
||||||
|
{"Generates CRL", "Generates CRL"}, //-gencrl
|
||||||
{"Imports entries from a JDK 1.1.x-style identity database",
|
{"Imports entries from a JDK 1.1.x-style identity database",
|
||||||
"Imports entries from a JDK 1.1.x-style identity database"}, //-identitydb
|
"Imports entries from a JDK 1.1.x-style identity database"}, //-identitydb
|
||||||
{"Imports a certificate or a certificate chain",
|
{"Imports a certificate or a certificate chain",
|
||||||
@ -87,6 +88,8 @@ public class Resources extends java.util.ListResourceBundle {
|
|||||||
"Prints the content of a certificate"}, //-printcert
|
"Prints the content of a certificate"}, //-printcert
|
||||||
{"Prints the content of a certificate request",
|
{"Prints the content of a certificate request",
|
||||||
"Prints the content of a certificate request"}, //-printcertreq
|
"Prints the content of a certificate request"}, //-printcertreq
|
||||||
|
{"Prints the content of a CRL file",
|
||||||
|
"Prints the content of a CRL file"}, //-printcrl
|
||||||
{"Generates a self-signed certificate",
|
{"Generates a self-signed certificate",
|
||||||
"Generates a self-signed certificate"}, //-selfcert
|
"Generates a self-signed certificate"}, //-selfcert
|
||||||
{"Changes the store password of a keystore",
|
{"Changes the store password of a keystore",
|
||||||
@ -176,6 +179,8 @@ public class Resources extends java.util.ListResourceBundle {
|
|||||||
"verbose output"}, //-v
|
"verbose output"}, //-v
|
||||||
{"validity number of days",
|
{"validity number of days",
|
||||||
"validity number of days"}, //-validity
|
"validity number of days"}, //-validity
|
||||||
|
{"Serial ID of cert to revoke",
|
||||||
|
"Serial ID of cert to revoke"}, //-id
|
||||||
// keytool: Running part
|
// keytool: Running part
|
||||||
{"keytool error: ", "keytool error: "},
|
{"keytool error: ", "keytool error: "},
|
||||||
{"Illegal option: ", "Illegal option: "},
|
{"Illegal option: ", "Illegal option: "},
|
||||||
@ -375,6 +380,7 @@ public class Resources extends java.util.ListResourceBundle {
|
|||||||
{"Signer #%d:", "Signer #%d:"},
|
{"Signer #%d:", "Signer #%d:"},
|
||||||
{"Timestamp:", "Timestamp:"},
|
{"Timestamp:", "Timestamp:"},
|
||||||
{"Signature:", "Signature:"},
|
{"Signature:", "Signature:"},
|
||||||
|
{"CRLs:", "CRLs:"},
|
||||||
{"Certificate owner: ", "Certificate owner: "},
|
{"Certificate owner: ", "Certificate owner: "},
|
||||||
{"Not a signed jar file", "Not a signed jar file"},
|
{"Not a signed jar file", "Not a signed jar file"},
|
||||||
{"No certificate from the SSL server",
|
{"No certificate from the SSL server",
|
||||||
@ -433,6 +439,7 @@ public class Resources extends java.util.ListResourceBundle {
|
|||||||
{"This extension cannot be marked as critical. ",
|
{"This extension cannot be marked as critical. ",
|
||||||
"This extension cannot be marked as critical. "},
|
"This extension cannot be marked as critical. "},
|
||||||
{"Odd number of hex digits found: ", "Odd number of hex digits found: "},
|
{"Odd number of hex digits found: ", "Odd number of hex digits found: "},
|
||||||
|
{"Unknown extension type: ", "Unknown extension type: "},
|
||||||
{"command {0} is ambiguous:", "command {0} is ambiguous:"},
|
{"command {0} is ambiguous:", "command {0} is ambiguous:"},
|
||||||
|
|
||||||
// policytool
|
// policytool
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright 1997-2009 Sun Microsystems, Inc. All Rights Reserved.
|
* Copyright 1997-2010 Sun Microsystems, Inc. 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
|
||||||
@ -25,7 +25,6 @@
|
|||||||
|
|
||||||
package sun.security.util;
|
package sun.security.util;
|
||||||
|
|
||||||
import java.security.CodeSigner;
|
|
||||||
import java.security.cert.CertPath;
|
import java.security.cert.CertPath;
|
||||||
import java.security.cert.X509Certificate;
|
import java.security.cert.X509Certificate;
|
||||||
import java.security.cert.CertificateException;
|
import java.security.cert.CertificateException;
|
||||||
@ -34,11 +33,11 @@ import java.security.*;
|
|||||||
import java.io.*;
|
import java.io.*;
|
||||||
import java.util.*;
|
import java.util.*;
|
||||||
import java.util.jar.*;
|
import java.util.jar.*;
|
||||||
import java.io.ByteArrayOutputStream;
|
|
||||||
|
|
||||||
import sun.security.pkcs.*;
|
import sun.security.pkcs.*;
|
||||||
import sun.security.timestamp.TimestampToken;
|
import sun.security.timestamp.TimestampToken;
|
||||||
import sun.misc.BASE64Decoder;
|
import sun.misc.BASE64Decoder;
|
||||||
|
import sun.misc.SharedSecrets;
|
||||||
|
|
||||||
import sun.security.jca.Providers;
|
import sun.security.jca.Providers;
|
||||||
|
|
||||||
@ -479,7 +478,12 @@ public class SignatureFileVerifier {
|
|||||||
signers = new ArrayList<CodeSigner>();
|
signers = new ArrayList<CodeSigner>();
|
||||||
}
|
}
|
||||||
// Append the new code signer
|
// Append the new code signer
|
||||||
signers.add(new CodeSigner(certChain, getTimestamp(info)));
|
CodeSigner signer = new CodeSigner(certChain, getTimestamp(info));
|
||||||
|
if (block.getCRLs() != null) {
|
||||||
|
SharedSecrets.getJavaSecurityCodeSignerAccess().setCRLs(
|
||||||
|
signer, block.getCRLs());
|
||||||
|
}
|
||||||
|
signers.add(signer);
|
||||||
|
|
||||||
if (debug != null) {
|
if (debug != null) {
|
||||||
debug.println("Signature Block Certificate: " +
|
debug.println("Signature Block Certificate: " +
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright 1997-2007 Sun Microsystems, Inc. All Rights Reserved.
|
* Copyright 1997-2010 Sun Microsystems, Inc. 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
|
||||||
@ -89,7 +89,7 @@ import sun.misc.HexDumpEncoder;
|
|||||||
* @author Hemma Prafullchandra
|
* @author Hemma Prafullchandra
|
||||||
* @see X509CRL
|
* @see X509CRL
|
||||||
*/
|
*/
|
||||||
public class X509CRLImpl extends X509CRL {
|
public class X509CRLImpl extends X509CRL implements DerEncoder {
|
||||||
|
|
||||||
// CRL data, and its envelope
|
// CRL data, and its envelope
|
||||||
private byte[] signedCRL = null; // DER encoded crl
|
private byte[] signedCRL = null; // DER encoded crl
|
||||||
@ -1189,6 +1189,13 @@ public class X509CRLImpl extends X509CRL {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void derEncode(OutputStream out) throws IOException {
|
||||||
|
if (signedCRL == null)
|
||||||
|
throw new IOException("Null CRL to encode");
|
||||||
|
out.write(signedCRL.clone());
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Immutable X.509 Certificate Issuer DN and serial number pair
|
* Immutable X.509 Certificate Issuer DN and serial number pair
|
||||||
*/
|
*/
|
||||||
|
91
jdk/test/sun/security/tools/jarsigner/crl.sh
Normal file
91
jdk/test/sun/security/tools/jarsigner/crl.sh
Normal file
@ -0,0 +1,91 @@
|
|||||||
|
#
|
||||||
|
# Copyright 2010 Sun Microsystems, Inc. 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
|
||||||
|
# CA 95054 USA or visit www.sun.com if you need additional information or
|
||||||
|
# have any questions.
|
||||||
|
#
|
||||||
|
|
||||||
|
# @test
|
||||||
|
# @bug 6890876
|
||||||
|
# @summary jarsigner can add CRL info into signed jar
|
||||||
|
#
|
||||||
|
|
||||||
|
if [ "${TESTJAVA}" = "" ] ; then
|
||||||
|
JAVAC_CMD=`which javac`
|
||||||
|
TESTJAVA=`dirname $JAVAC_CMD`/..
|
||||||
|
fi
|
||||||
|
|
||||||
|
# set platform-dependent variables
|
||||||
|
# PF: platform name, say, solaris-sparc
|
||||||
|
|
||||||
|
PF=""
|
||||||
|
|
||||||
|
OS=`uname -s`
|
||||||
|
case "$OS" in
|
||||||
|
Windows* )
|
||||||
|
FS="\\"
|
||||||
|
;;
|
||||||
|
* )
|
||||||
|
FS="/"
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
|
||||||
|
KS=crl.jks
|
||||||
|
JFILE=crl.jar
|
||||||
|
|
||||||
|
KT="$TESTJAVA${FS}bin${FS}keytool -storepass changeit -keypass changeit -keystore $KS"
|
||||||
|
JAR=$TESTJAVA${FS}bin${FS}jar
|
||||||
|
JARSIGNER=$TESTJAVA${FS}bin${FS}jarsigner
|
||||||
|
|
||||||
|
rm $KS $JFILE
|
||||||
|
|
||||||
|
# Generates some crl files, each containing two entries
|
||||||
|
|
||||||
|
$KT -alias a -dname CN=a -keyalg rsa -genkey -validity 300
|
||||||
|
$KT -alias a -gencrl -id 1:1 -id 2:2 -file crl1
|
||||||
|
$KT -alias a -gencrl -id 3:3 -id 4:4 -file crl2
|
||||||
|
$KT -alias b -dname CN=b -keyalg rsa -genkey -validity 300
|
||||||
|
$KT -alias b -gencrl -id 5:1 -id 6:2 -file crl3
|
||||||
|
|
||||||
|
$KT -alias c -dname CN=c -keyalg rsa -genkey -validity 300 \
|
||||||
|
-ext crl=uri:file://`pwd`/crl1
|
||||||
|
|
||||||
|
echo A > A
|
||||||
|
|
||||||
|
# Test -crl:auto, cRLDistributionPoints is a local file
|
||||||
|
|
||||||
|
$JAR cvf $JFILE A
|
||||||
|
$JARSIGNER -keystore $KS -storepass changeit $JFILE c \
|
||||||
|
-crl:auto || exit 1
|
||||||
|
$JARSIGNER -keystore $KS -verify -debug -strict $JFILE || exit 6
|
||||||
|
$KT -printcert -jarfile $JFILE | grep CRLs || exit 7
|
||||||
|
|
||||||
|
# Test -crl <file>
|
||||||
|
|
||||||
|
$JAR cvf $JFILE A
|
||||||
|
$JARSIGNER -keystore $KS -storepass changeit $JFILE a \
|
||||||
|
-crl crl1 -crl crl2 || exit 1
|
||||||
|
$JARSIGNER -keystore $KS -storepass changeit $JFILE b \
|
||||||
|
-crl crl3 -crl crl2 || exit 1
|
||||||
|
$JARSIGNER -keystore $KS -verify -debug -strict $JFILE || exit 3
|
||||||
|
$KT -printcert -jarfile $JFILE | grep CRLs || exit 4
|
||||||
|
CRLCOUNT=`$KT -printcert -jarfile $JFILE | grep SerialNumber | wc -l`
|
||||||
|
if [ $CRLCOUNT != 8 ]; then exit 5; fi
|
||||||
|
|
||||||
|
exit 0
|
Loading…
x
Reference in New Issue
Block a user