/*
* Part of the CCNx Java Library.
*
* Copyright (C) 2008, 2009, 2010 Palo Alto Research Center, Inc.
*
* This library is free software; you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License version 2.1
* as published by the Free Software Foundation.
* This library 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
* Lesser General Public License for more details. You should have received
* a copy of the GNU Lesser General Public License along with this library;
* if not, write to the Free Software Foundation, Inc., 51 Franklin Street,
* Fifth Floor, Boston, MA 02110-1301 USA.
*/
package org.ccnx.ccn.impl.security.crypto.util;
import java.math.BigInteger;
import java.net.URI;
import java.util.Enumeration;
import org.bouncycastle.asn1.ASN1EncodableVector;
import org.bouncycastle.asn1.ASN1OctetString;
import org.bouncycastle.asn1.ASN1Sequence;
import org.bouncycastle.asn1.ASN1TaggedObject;
import org.bouncycastle.asn1.DEREncodable;
import org.bouncycastle.asn1.DERInteger;
import org.bouncycastle.asn1.DERObject;
import org.bouncycastle.asn1.DEROctetString;
import org.bouncycastle.asn1.DERSequence;
import org.bouncycastle.asn1.DERTaggedObject;
import org.bouncycastle.asn1.DERTags;
import org.bouncycastle.asn1.x509.GeneralName;
import org.bouncycastle.asn1.x509.GeneralNames;
/**
* Reimplementation of BouncyCastle's AuthorityKeyIdentifier to allow
* keyID to be set.
*
* We must take authority key id from subject key id field of
* issuer's certificate if present; algorithm is not required by the standard so
* may not match.
* <pre>
* id-ce-authorityKeyIdentifier OBJECT IDENTIFIER ::= { id-ce 35 }
*
* AuthorityKeyIdentifier ::= SEQUENCE {
* keyIdentifier [0] IMPLICIT KeyIdentifier OPTIONAL,
* authorityCertIssuer [1] IMPLICIT GeneralNames OPTIONAL,
* authorityCertSerialNumber [2] IMPLICIT CertificateSerialNumber OPTIONAL }
*
* KeyIdentifier ::= OCTET STRING
* </pre>
*/
public class AuthorityKeyIdentifier implements DEREncodable, DERTags {
public static final int tag_KeyIdentifier = 0;
public static final int tag_IssuerName = 1;
public static final int tag_issuerSerialNumber = 2;
protected ASN1OctetString _keyIdentifier = null;
protected GeneralNames _issuerName = null;
protected DERInteger _issuerSerial = null;
public static AuthorityKeyIdentifier getInstance(ASN1TaggedObject obj,
boolean explicit) {
return getInstance(ASN1Sequence.getInstance(obj, explicit));
}
public static AuthorityKeyIdentifier getInstance(Object obj) {
if (obj instanceof AuthorityKeyIdentifier)
return (AuthorityKeyIdentifier)obj;
else if (obj instanceof ASN1Sequence) {
return new AuthorityKeyIdentifier((ASN1Sequence)obj);
}
throw new IllegalArgumentException("Cannot construct an AuthorityKeyIdentifier from a: " +
obj.getClass().getName());
}
public AuthorityKeyIdentifier(ASN1Sequence seq) {
Enumeration<?> e = seq.getObjects();
DERTaggedObject o = null;
while (e.hasMoreElements()) {
o = (DERTaggedObject)e.nextElement();
switch (o.getTagNo()) {
case tag_KeyIdentifier:
this._keyIdentifier = ASN1OctetString.getInstance(o);
break;
case tag_IssuerName:
this._issuerName = GeneralNames.getInstance(o);
break;
case tag_issuerSerialNumber:
this._issuerSerial = DERInteger.getInstance(o);
break;
default:
throw new IllegalArgumentException("Illegal tag: " + o.getTagNo());
}
}
}
public AuthorityKeyIdentifier(byte [] keyID, GeneralNames issuerName, BigInteger issuerSerial) {
if (null != keyID)
this._keyIdentifier = new DEROctetString(keyID);
this._issuerName = issuerName; // clone if not null?
if (null != issuerSerial)
this._issuerSerial = new DERInteger(issuerSerial);
}
public AuthorityKeyIdentifier(byte [] keyID) {
this(keyID, null, null);
}
public byte [] getKeyIdentifier() {
if (this._keyIdentifier != null)
return this._keyIdentifier.getOctets();
return null;
}
public void setKeyIdentifier(byte [] keyID) {
if (null != keyID)
this._keyIdentifier = new DEROctetString(keyID);
}
public GeneralNames getIssuerName() {
return this._issuerName;
}
public void setIssuerName(GeneralNames name) {
this._issuerName = name; // clone?
}
/*
* Helper method
*/
public void setIssuerName(URI uri) {
GeneralName name = new GeneralName(GeneralName.uniformResourceIdentifier, uri.toString());
this._issuerName = new GeneralNames(name); // clone?
}
public BigInteger getIssuerSerialNumber() {
if (null != this._issuerSerial)
return this._issuerSerial.getValue();
return null;
}
public void setIssuerSerialNumber(BigInteger serial) {
if (null != serial)
this._issuerSerial = new DERInteger(serial);
}
/**
* <pre>
* AuthorityKeyIdentifier ::= SEQUENCE {
* keyIdentifier [0] IMPLICIT KeyIdentifier OPTIONAL,
* authorityCertIssuer [1] IMPLICIT GeneralNames OPTIONAL,
* authorityCertSerialNumber [2] IMPLICIT CertificateSerialNumber OPTIONAL }
*
* KeyIdentifier ::= OCTET STRING
* </pre>
*/
public DERObject getDERObject() {
ASN1EncodableVector seq = new ASN1EncodableVector();
if (null != this._keyIdentifier)
seq.add(new DERTaggedObject(false, tag_KeyIdentifier, _keyIdentifier));
if (null != this._issuerName)
seq.add(new DERTaggedObject(false, tag_IssuerName, _issuerName));
if (null != this._issuerSerial)
seq.add(new DERTaggedObject(false, tag_issuerSerialNumber, _issuerSerial));
return new DERSequence(seq);
}
public String toString() {
StringBuffer buf = new StringBuffer("AuthorityKeyIdentifier:");
buf.append('\n');
if (null != _keyIdentifier) {
buf.append(" KeyID:");
buf.append(new BigInteger(this._keyIdentifier.getOctets()).toString(16));
buf.append('\n');
}
if (null != _issuerName) {
buf.append(" Issuer:");
buf.append(_issuerName.toString());
buf.append('\n');
}
if (null != _issuerSerial) {
buf.append(" Issuer Serial Number:");
buf.append(this._issuerSerial.getValue().toString(16));
buf.append('\n');
}
return buf.toString();
}
}