/*
* Copyright 2014 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package java.security.cert;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.util.Collections;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;
import javax.security.auth.x500.X500Principal;
import org.apache.harmony.security.x509.InvalidityDate;
/**
* Exception that is thrown when a certificate is invalid because it has been
* revoked.
*
* @since 1.7
* @hide
*/
public class CertificateRevokedException extends CertificateException {
private static final long serialVersionUID = 7839996631571608627L;
private final Date revocationDate;
private final CRLReason reason;
private final X500Principal authority;
// Maps may not be serializable, so serialize it manually.
private transient Map<String, Extension> extensions;
/**
* @param revocationDate date the certificate was revoked
* @param reason reason the certificate was revoked if available
* @param authority authority that revoked the certificate
* @param extensions X.509 extensions associated with this revocation
*/
public CertificateRevokedException(Date revocationDate, CRLReason reason,
X500Principal authority, Map<String, Extension> extensions) {
this.revocationDate = revocationDate;
this.reason = reason;
this.authority = authority;
this.extensions = extensions;
}
/**
* Returns the principal of the authority that issued the revocation.
*/
public X500Principal getAuthorityName() {
return authority;
}
/**
* X.509 extensions that are associated with this revocation.
*/
public Map<String, Extension> getExtensions() {
return Collections.unmodifiableMap(extensions);
}
/**
* Returns the date when the certificate was known to become invalid if
* available.
*/
public Date getInvalidityDate() {
if (extensions == null) {
return null;
}
Extension invalidityDateExtension = extensions.get("2.5.29.24");
if (invalidityDateExtension == null) {
return null;
}
try {
InvalidityDate invalidityDate = new InvalidityDate(invalidityDateExtension.getValue());
return invalidityDate.getDate();
} catch (IOException e) {
return null;
}
}
/**
* Returns the detail message of the thrown exception.
*/
public String getMessage() {
StringBuffer sb = new StringBuffer("Certificate was revoked");
if (revocationDate != null) {
sb.append(" on ").append(revocationDate.toString());
}
if (reason != null) {
sb.append(" due to ").append(reason);
}
return sb.toString();
}
/**
* Returns the date the certificate was revoked.
*/
public Date getRevocationDate() {
return (Date) revocationDate.clone();
}
/**
* Returns the reason the certificate was revoked if available.
*/
public CRLReason getRevocationReason() {
return reason;
}
private void readObject(ObjectInputStream stream) throws IOException, ClassNotFoundException {
stream.defaultReadObject();
int size = stream.readInt();
extensions = new HashMap<String, Extension>(size);
for (int i = 0; i < size; i++) {
String oid = (String) stream.readObject();
boolean critical = stream.readBoolean();
int valueLen = stream.readInt();
byte[] value = new byte[valueLen];
stream.read(value);
extensions.put(oid,
new org.apache.harmony.security.x509.Extension(oid, critical, value));
}
}
private void writeObject(ObjectOutputStream stream) throws IOException {
stream.defaultWriteObject();
stream.writeInt(extensions.size());
for (Extension e : extensions.values()) {
stream.writeObject(e.getId());
stream.writeBoolean(e.isCritical());
byte[] value = e.getValue();
stream.writeInt(value.length);
stream.write(value);
}
}
}