/*
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle 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 Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
/**
* <p>
* An implementation for X509 CRL (Certificate Revocation List).
* <p>
* The X.509 v2 CRL format is described below in ASN.1:
* <pre>
* CertificateList ::= SEQUENCE {
* tbsCertList TBSCertList,
* signatureAlgorithm AlgorithmIdentifier,
* signature BIT STRING }
* </pre>
* More information can be found in
* <a href="http://www.ietf.org/rfc/rfc3280.txt">RFC 3280: Internet X.509
* Public Key Infrastructure Certificate and CRL Profile</a>.
* <p>
* The ASN.1 definition of <code>tbsCertList</code> is:
* <pre>
* TBSCertList ::= SEQUENCE {
* version Version OPTIONAL,
* -- if present, must be v2
* signature AlgorithmIdentifier,
* issuer Name,
* thisUpdate ChoiceOfTime,
* nextUpdate ChoiceOfTime OPTIONAL,
* revokedCertificates SEQUENCE OF SEQUENCE {
* userCertificate CertificateSerialNumber,
* revocationDate ChoiceOfTime,
* crlEntryExtensions Extensions OPTIONAL
* -- if present, must be v2
* } OPTIONAL,
* crlExtensions [0] EXPLICIT Extensions OPTIONAL
* -- if present, must be v2
* }
* </pre>
*
* @author Hemma Prafullchandra
* @see X509CRL
*/
// CRL data, and its envelope
// crl information
private int version;
private final static boolean isExplicit = true;
private boolean readOnly = false;
/**
* PublicKey that has previously been used to successfully verify
* the signature of this CRL. Null if the CRL has not
* yet been verified (successfully).
*/
/**
* If verifiedPublicKey is not null, name of the provider used to
* successfully verify the signature of this CRL, or the
* empty String if no provider was explicitly specified.
*/
/**
* Not to be used. As it would lead to cases of uninitialized
* CRL objects.
*/
private X509CRLImpl() { }
/**
* Unmarshals an X.509 CRL from its encoded form, parsing the encoded
* bytes. This form of constructor is used by agents which
* need to examine and use CRL contents. Note that the buffer
* must include only one CRL, and no "garbage" may be left at
* the end.
*
* @param crlData the encoded bytes, with no trailing padding.
* @exception CRLException on parsing errors.
*/
try {
} catch (IOException e) {
}
}
/**
* Unmarshals an X.509 CRL from an DER value.
*
* @param val a DER value holding at least one CRL
* @exception CRLException on parsing errors.
*/
try {
} catch (IOException e) {
}
}
/**
* Unmarshals an X.509 CRL from an input stream. Only one CRL
* is expected at the end of the input stream.
*
* @param inStrm an input stream holding at least one CRL
* @exception CRLException on parsing errors.
*/
try {
} catch (IOException e) {
}
}
/**
* Initial CRL constructor, no revoked certs, and no extensions.
*
* @param issuer the name of the CA issuing this CRL.
* @param thisUpdate the Date of this issue.
* @param nextUpdate the Date of the next CRL.
*/
this.thisUpdate = thisDate;
this.nextUpdate = nextDate;
}
/**
* CRL constructor, revoked certs, no extensions.
*
* @param issuer the name of the CA issuing this CRL.
* @param thisUpdate the Date of this issue.
* @param nextUpdate the Date of the next CRL.
* @param badCerts the array of CRL entries.
*
* @exception CRLException on parsing/construction errors.
*/
throws CRLException
{
this.thisUpdate = thisDate;
this.nextUpdate = nextDate;
try {
} catch (IOException ioe) {
throw new CRLException(ioe);
}
if (badCert.hasExtensions()) {
this.version = 1;
}
}
}
}
/**
* CRL constructor, revoked certs and extensions.
*
* @param issuer the name of the CA issuing this CRL.
* @param thisUpdate the Date of this issue.
* @param nextUpdate the Date of the next CRL.
* @param badCerts the array of CRL entries.
* @param crlExts the CRL extensions.
*
* @exception CRLException on parsing/construction errors.
*/
throws CRLException
{
this.extensions = crlExts;
this.version = 1;
}
}
/**
* Returned the encoding as an uncloned byte array. Callers must
* guarantee that they neither modify it nor expose it to untrusted
* code.
*/
throw new CRLException("Null CRL to encode");
}
return signedCRL;
}
/**
* Returns the ASN.1 DER encoded form of this CRL.
*
* @exception CRLException if an encoding error occurs.
*/
return getEncodedInternal().clone();
}
/**
* Encodes the "to-be-signed" CRL to the OutputStream.
*
* @param out the OutputStream to write to.
* @exception CRLException on encoding errors.
*/
try {
throw new CRLException("Null Issuer DN not allowed in v1 CRL");
else
if (nextUpdate != null) {
else
}
if (!revokedList.isEmpty()) {
}
}
if (extensions != null)
} catch (IOException e) {
}
}
/**
* Verifies that this CRL was signed using the
* private key that corresponds to the given public key.
*
* @param key the PublicKey used to carry out the verification.
*
* @exception NoSuchAlgorithmException on unsupported signature
* algorithms.
* @exception InvalidKeyException on incorrect key.
* @exception NoSuchProviderException if there's no default provider.
* @exception SignatureException on signature errors.
* @exception CRLException on encoding errors.
*/
}
/**
* Verifies that this CRL was signed using the
* private key that corresponds to the given public key,
* and that the signature verification was computed by
* the given provider.
*
* @param key the PublicKey used to carry out the verification.
* @param sigProvider the name of the signature provider.
*
* @exception NoSuchAlgorithmException on unsupported signature
* algorithms.
* @exception InvalidKeyException on incorrect key.
* @exception NoSuchProviderException on incorrect provider.
* @exception SignatureException on signature errors.
* @exception CRLException on encoding errors.
*/
if (sigProvider == null) {
sigProvider = "";
}
// this CRL has already been successfully verified using
// this public key. Make sure providers match, too.
return;
}
}
throw new CRLException("Uninitialized CRL");
}
} else {
}
if (tbsCertList == null) {
throw new CRLException("Uninitialized CRL");
}
throw new SignatureException("Signature does not match.");
}
}
/**
* Encodes an X.509 CRL, and signs it using the given key.
*
* @param key the private key used for signing.
* @param algorithm the name of the signature algorithm used.
*
* @exception NoSuchAlgorithmException on unsupported signature
* algorithms.
* @exception InvalidKeyException on incorrect key.
* @exception NoSuchProviderException on incorrect provider.
* @exception SignatureException on signature errors.
* @exception CRLException if any mandatory data was omitted.
*/
}
/**
* Encodes an X.509 CRL, and signs it using the given key.
*
* @param key the private key used for signing.
* @param algorithm the name of the signature algorithm used.
* @param provider the name of the provider.
*
* @exception NoSuchAlgorithmException on unsupported signature
* algorithms.
* @exception InvalidKeyException on incorrect key.
* @exception NoSuchProviderException on incorrect provider.
* @exception SignatureException on signature errors.
* @exception CRLException if any mandatory data was omitted.
*/
try {
if (readOnly)
throw new CRLException("cannot over-write existing CRL");
else
// in case the name is reset
// encode crl info
// encode algorithm identifier
// Create and encode the signature itself.
// Wrap the signed data in a SEQUENCE { data, algorithm, sig }
readOnly = true;
} catch (IOException e) {
throw new CRLException("Error while encoding data: " +
e.getMessage());
}
}
/**
* Returns a printable string of this CRL.
*
* @return value of this CRL in a printable form.
*/
if (thisUpdate != null)
if (nextUpdate != null)
if (revokedList.isEmpty())
else {
int i = 1;
}
}
if (extensions != null) {
try {
+ "DER encoded OCTET string =\n"
}
} else
} catch (Exception e) {
}
}
}
+ "\n");
} else
}
/**
* Checks whether the given certificate is on this CRL.
*
* @param cert the certificate to check for.
* @return true if the given certificate is on this CRL,
* false otherwise.
*/
return false;
}
}
/**
* Gets the version number from this CRL.
* The ASN.1 definition for this is:
* <pre>
* Version ::= INTEGER { v1(0), v2(1), v3(2) }
* -- v3 does not apply to CRLs but appears for consistency
* -- with definition of Version for certs
* </pre>
* @return the version number, i.e. 1 or 2.
*/
public int getVersion() {
return version+1;
}
/**
* Gets the issuer distinguished name from this CRL.
* The issuer name identifies the entity who has signed (and
* issued the CRL). The issuer name field contains an
* X.500 distinguished name (DN).
* The ASN.1 definition for this is:
* <pre>
* issuer Name
*
* Name ::= CHOICE { RDNSequence }
* RDNSequence ::= SEQUENCE OF RelativeDistinguishedName
* RelativeDistinguishedName ::=
* SET OF AttributeValueAssertion
*
* AttributeValueAssertion ::= SEQUENCE {
* AttributeType,
* AttributeValue }
* AttributeType ::= OBJECT IDENTIFIER
* AttributeValue ::= ANY
* </pre>
* The Name describes a hierarchical name composed of attributes,
* such as country name, and corresponding values, such as US.
* The type of the component AttributeValue is determined by the
* AttributeType; in general it will be a directoryString.
* A directoryString is usually one of PrintableString,
* TeletexString or UniversalString.
* @return the issuer name.
*/
}
/**
* Return the issuer as X500Principal. Overrides method in X509CRL
* to provide a slightly more efficient version.
*/
if (issuerPrincipal == null) {
}
return issuerPrincipal;
}
/**
* Gets the thisUpdate date from the CRL.
* The ASN.1 definition for this is:
*
* @return the thisUpdate date from the CRL.
*/
}
/**
* Gets the nextUpdate date from the CRL.
*
* @return the nextUpdate date from the CRL, or null if
* not present.
*/
if (nextUpdate == null)
return null;
}
/**
* Gets the CRL entry with the given serial number from this CRL.
*
* @return the entry with the given serial number, or <code>null</code> if
* no such entry exists in the CRL.
* @see X509CRLEntry
*/
if (revokedMap.isEmpty()) {
return null;
}
// assume this is a direct CRL entry (cert and CRL issuer are the same)
}
/**
* Gets the CRL entry for the given certificate.
*/
if (revokedMap.isEmpty()) {
return null;
}
}
/**
* Gets all the revoked certificates from the CRL.
* A Set of X509CRLEntry.
*
* @return all the revoked certificates or <code>null</code> if there are
* none.
* @see X509CRLEntry
*/
if (revokedList.isEmpty()) {
return null;
} else {
}
}
/**
* Gets the DER encoded CRL information, the
* <code>tbsCertList</code> from this CRL.
* This can be used to verify the signature independently.
*
* @return the DER encoded CRL information.
* @exception CRLException on encoding errors.
*/
if (tbsCertList == null)
throw new CRLException("Uninitialized CRL");
return dup;
}
/**
* Gets the raw Signature bits from the CRL.
*
* @return the signature.
*/
public byte[] getSignature() {
return null;
return dup;
}
/**
* Gets the signature algorithm name for the CRL
* signature algorithm. For example, the string "SHA1withDSA".
* The ASN.1 definition for this is:
* <pre>
* AlgorithmIdentifier ::= SEQUENCE {
* algorithm OBJECT IDENTIFIER,
* parameters ANY DEFINED BY algorithm OPTIONAL }
* -- contains a value of the type
* -- registered for use with the
* -- algorithm object identifier value
* </pre>
*
* @return the signature algorithm name.
*/
return null;
}
/**
* Gets the signature algorithm OID string from the CRL.
* An OID is represented by a set of positive whole number separated
* by ".", that means,<br>
* <positive whole number>.<positive whole number>.<...>
* For example, the string "1.2.840.10040.4.3" identifies the SHA-1
* with DSA signature algorithm defined in
* <a href="http://www.ietf.org/rfc/rfc3279.txt">RFC 3279: Algorithms and
* Identifiers for the Internet X.509 Public Key Infrastructure Certificate
* and CRL Profile</a>.
*
* @return the signature algorithm oid string.
*/
return null;
}
/**
* Gets the DER encoded signature algorithm parameters from this
* CRL's signature algorithm. In most cases, the signature
* algorithm parameters are null, the parameters are usually
* supplied with the Public Key.
*
* @return the DER encoded signature algorithm parameters, or
* null if no parameters are present.
*/
public byte[] getSigAlgParams() {
return null;
try {
return sigAlgId.getEncodedParams();
} catch (IOException e) {
return null;
}
}
/**
* Gets the signature AlgorithmId from the CRL.
*
* @return the signature AlgorithmId
*/
return sigAlgId;
}
/**
* return the AuthorityKeyIdentifier, if any.
*
* @returns AuthorityKeyIdentifier or null
* (if no AuthorityKeyIdentifierExtension)
* @throws IOException on error
*/
return keyId;
} else {
return null;
}
}
/**
* return the AuthorityKeyIdentifierExtension, if any.
*
* @returns AuthorityKeyIdentifierExtension or null (if no such extension)
* @throws IOException on error
*/
throws IOException {
return (AuthorityKeyIdentifierExtension)obj;
}
/**
* return the CRLNumberExtension, if any.
*
* @returns CRLNumberExtension or null (if no such extension)
* @throws IOException on error
*/
return (CRLNumberExtension)obj;
}
/**
* return the CRL number from the CRLNumberExtension, if any.
*
* @returns number or null (if no such extension)
* @throws IOException on error
*/
return num;
} else {
return null;
}
}
/**
* return the DeltaCRLIndicatorExtension, if any.
*
* @returns DeltaCRLIndicatorExtension or null (if no such extension)
* @throws IOException on error
*/
throws IOException {
return (DeltaCRLIndicatorExtension)obj;
}
/**
* return the base CRL number from the DeltaCRLIndicatorExtension, if any.
*
* @returns number or null (if no such extension)
* @throws IOException on error
*/
return num;
} else {
return null;
}
}
/**
* return the IssuerAlternativeNameExtension, if any.
*
* @returns IssuerAlternativeNameExtension or null (if no such extension)
* @throws IOException on error
*/
throws IOException {
return (IssuerAlternativeNameExtension)obj;
}
/**
* return the IssuingDistributionPointExtension, if any.
*
* @returns IssuingDistributionPointExtension or null
* (if no such extension)
* @throws IOException on error
*/
return (IssuingDistributionPointExtension) obj;
}
/**
* Return true if a critical extension is found that is
* not supported, otherwise return false.
*/
public boolean hasUnsupportedCriticalExtension() {
if (extensions == null)
return false;
return extensions.hasUnsupportedCriticalExtension();
}
/**
* Gets a Set of the extension(s) marked CRITICAL in the
* CRL. In the returned set, each extension is represented by
* its OID string.
*
* @return a set of the extension oid strings in the
* CRL that are marked critical.
*/
if (extensions == null) {
return null;
}
if (ex.isCritical()) {
}
}
return extSet;
}
/**
* Gets a Set of the extension(s) marked NON-CRITICAL in the
* CRL. In the returned set, each extension is represented by
* its OID string.
*
* @return a set of the extension oid strings in the
* CRL that are NOT marked critical.
*/
if (extensions == null) {
return null;
}
if (!ex.isCritical()) {
}
}
return extSet;
}
/**
* Gets the DER encoded OCTET string for the extension value
* (<code>extnValue</code>) identified by the passed in oid String.
* The <code>oid</code> string is
* represented by a set of positive whole number separated
* by ".", that means,<br>
* <positive whole number>.<positive whole number>.<...>
*
* @param oid the Object Identifier value for the extension.
* @return the der encoded octet string of the extension value.
*/
if (extensions == null)
return null;
try {
e.hasMoreElements();) {
ex = e.nextElement();
break;
}
}
} else
return null;
return null;
return out.toByteArray();
} catch (Exception e) {
return null;
}
}
/**
* get an extension
*
* @param oid ObjectIdentifier of extension desired
* @returns Object of type <extension> or null, if not found
* @throws IOException on error
*/
if (extensions == null)
return null;
// XXX Consider cloning this
}
/*
* Parses an X.509 CRL, should be used only by constructors.
*/
// check if can over write the certificate
if (readOnly)
throw new CRLException("cannot over-write existing CRL");
throw new CRLException("Invalid DER-encoded CRL data");
throw new CRLException("signed overrun, bytes = "
throw new CRLException("signed CRL fields invalid");
throw new CRLException("AlgorithmId field overrun");
throw new CRLException("Signature field overrun");
// the tbsCertsList
// parse the information
byte nextByte;
// version (optional if v1)
throw new CRLException("Invalid version");
}
// signature
// the "inner" and "outer" signature algorithms must match
throw new CRLException("Signature algorithm mismatch");
// issuer
throw new CRLException("Empty issuer DN not allowed in X509CRLs");
}
// thisUpdate
// check if UTCTime encoded or GeneralizedTime
} else {
throw new CRLException("Invalid encoding for thisUpdate"
}
return; // done parsing no more optional fields present
// nextUpdate (optional)
} // else it is not present
return; // done parsing no more optional fields present
// revokedCertificates (optional)
}
}
return; // done parsing no extensions
// crlExtensions (optional)
}
readOnly = true;
}
/**
* Extract the issuer X500Principal from an X509CRL. Parses the encoded
* form of the CRL to preserve the principal's ASN.1 encoding.
*
* Called by java.security.cert.X509CRL.getIssuerX500Principal().
*/
try {
// skip version number if present
}
return new X500Principal(principalBytes);
} catch (Exception e) {
throw new RuntimeException("Could not parse issuer", e);
}
}
/**
* Returned the encoding of the given certificate for internal use.
* Callers must guarantee that they neither modify it nor expose it
* to untrusted code. Uses getEncodedInternal() if the certificate
* is instance of X509CertImpl, getEncoded() otherwise.
*/
if (crl instanceof X509CRLImpl) {
} else {
return crl.getEncoded();
}
}
/**
* Utility method to convert an arbitrary instance of X509CRL
* to a X509CRLImpl. Does a cast if possible, otherwise reparses
* the encoding.
*/
throws CRLException {
if (crl instanceof X509CRLImpl) {
return (X509CRLImpl)crl;
} else {
}
}
/**
* Returns the X500 certificate issuer DN of a CRL entry.
*
* @param entry the entry to check
* @param prevCertIssuer the previous entry's certificate issuer
* @return the X500Principal in a CertificateIssuerExtension, or
* prevCertIssuer if it does not exist
*/
return issuerDN.asX500Principal();
} else {
return prevCertIssuer;
}
}
throw new IOException("Null CRL to encode");
}
/**
* Immutable X.509 Certificate Issuer DN and serial number pair
*/
private final static class X509IssuerSerial
implements Comparable<X509IssuerSerial> {
/**
* Create an X509IssuerSerial.
*
* @param issuer the issuer DN
* @param serial the serial number
*/
}
/**
* Construct an X509IssuerSerial from an X509Certificate.
*/
}
/**
* Returns the issuer.
*
* @return the issuer
*/
return issuer;
}
/**
* Returns the serial number.
*
* @return the serial number
*/
return serial;
}
/**
* Compares this X509Serial with another and returns true if they
* are equivalent.
*
* @param o the other object to compare with
* @return true if equal, false otherwise
*/
if (o == this) {
return true;
}
if (!(o instanceof X509IssuerSerial)) {
return false;
}
return true;
}
return false;
}
/**
* Returns a hash code value for this X509IssuerSerial.
*
* @return the hash code value
*/
public int hashCode() {
if (hashcode == 0) {
int result = 17;
}
return hashcode;
}
}
}
}