blob: 57116301c0ebc30ed55cf21d7956154b3294e8a0 [file] [log] [blame]
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You 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.
*/
/**
* @author Alexander Y. Kleymenov
* @version $Revision$
*/
package org.apache.harmony.security.x509;
import java.math.BigInteger;
import javax.security.auth.x500.X500Principal;
import org.apache.harmony.security.asn1.ASN1BitString;
import org.apache.harmony.security.asn1.ASN1Explicit;
import org.apache.harmony.security.asn1.ASN1Implicit;
import org.apache.harmony.security.asn1.ASN1Integer;
import org.apache.harmony.security.asn1.ASN1Sequence;
import org.apache.harmony.security.asn1.ASN1Type;
import org.apache.harmony.security.asn1.BerInputStream;
import org.apache.harmony.security.asn1.BitString;
import org.apache.harmony.security.x501.Name;
/**
* The class encapsulates the ASN.1 DER encoding/decoding work
* with TBSCertificate structure which is the part of X.509 certificate
* (as specified in RFC 3280 -
* Internet X.509 Public Key Infrastructure.
* Certificate and Certificate Revocation List (CRL) Profile.
* http://www.ietf.org/rfc/rfc3280.txt):
*
* <pre>
* TBSCertificate ::= SEQUENCE {
* version [0] EXPLICIT Version DEFAULT v1,
* serialNumber CertificateSerialNumber,
* signature AlgorithmIdentifier,
* issuer Name,
* validity Validity,
* subject Name,
* subjectPublicKeyInfo SubjectPublicKeyInfo,
* issuerUniqueID [1] IMPLICIT UniqueIdentifier OPTIONAL,
* -- If present, version MUST be v2 or v3
* subjectUniqueID [2] IMPLICIT UniqueIdentifier OPTIONAL,
* -- If present, version MUST be v2 or v3
* extensions [3] EXPLICIT Extensions OPTIONAL
* -- If present, version MUST be v3
* }
* </pre>
*/
public class TBSCertificate {
// the value of version field of the structure
private final int version;
// the value of serialNumber field of the structure
private final BigInteger serialNumber;
// the value of signature field of the structure
private final AlgorithmIdentifier signature;
// the value of issuer field of the structure
private final Name issuer;
// the value of validity field of the structure
private final Validity validity;
// the value of subject field of the structure
private final Name subject;
// the value of subjectPublicKeyInfo field of the structure
private final SubjectPublicKeyInfo subjectPublicKeyInfo;
// the value of issuerUniqueID field of the structure
private final boolean[] issuerUniqueID;
// the value of subjectUniqueID field of the structure
private final boolean[] subjectUniqueID;
// the value of extensions field of the structure
private final Extensions extensions;
// the ASN.1 encoded form of TBSCertificate
byte[] encoding;
/**
* Constructs the instance of TBSCertificate without optional
* fields (issuerUniqueID, subjectUniqueID, extensions)
* @param version : int
* @param serialNumber : BigInteger
* @param signature : AlgorithmIdentifier
* @param issuer : Name
* @param validity : Validity
* @param subject : Name
* @param subjectPublicKeyInfo : SubjectPublicKeyInfo
*/
public TBSCertificate(int version, BigInteger serialNumber,
AlgorithmIdentifier signature, Name issuer,
Validity validity, Name subject,
SubjectPublicKeyInfo subjectPublicKeyInfo) {
this(version, serialNumber, signature, issuer, validity, subject,
subjectPublicKeyInfo, null, null, null);
}
/**
* TODO
* @param version: int
* @param serialNumber: BigInteger
* @param signature: AlgorithmIdentifier
* @param issuer: Name
* @param validity: Validity
* @param subject: Name
* @param subjectPublicKeyInfo: SubjectPublicKeyInfo
* @param issuerUniqueID: byte[]
* @param subjectUniqueID: byte[]
* @param extensions: Extensions
*/
public TBSCertificate(int version, BigInteger serialNumber,
AlgorithmIdentifier signature, Name issuer,
Validity validity, Name subject,
SubjectPublicKeyInfo subjectPublicKeyInfo,
boolean[] issuerUniqueID, boolean[] subjectUniqueID,
Extensions extensions) {
this.version = version;
this.serialNumber = serialNumber;
this.signature = signature;
this.issuer = issuer;
this.validity = validity;
this.subject = subject;
this.subjectPublicKeyInfo = subjectPublicKeyInfo;
this.issuerUniqueID = issuerUniqueID;
this.subjectUniqueID = subjectUniqueID;
this.extensions = extensions;
}
//
// TODO
// @param version: int
// @param serialNumber: BigInteger
// @param signature: AlgorithmIdentifier
// @param issuer: Name
// @param validity: Validity
// @param subject: Name
// @param subjectPublicKeyInfo: SubjectPublicKeyInfo
// @param issuerUniqueID: byte[]
// @param subjectUniqueID: byte[]
// @param extensions: Extensions
// @param encoding: byte[]
//
private TBSCertificate(int version, BigInteger serialNumber,
AlgorithmIdentifier signature, Name issuer,
Validity validity, Name subject,
SubjectPublicKeyInfo subjectPublicKeyInfo,
boolean[] issuerUniqueID, boolean[] subjectUniqueID,
Extensions extensions, byte[] encoding) {
this(version, serialNumber, signature, issuer, validity, subject,
subjectPublicKeyInfo, issuerUniqueID, subjectUniqueID, extensions);
this.encoding = encoding;
}
/**
* Returns the value of version field of the structure.
* @return version
*/
public int getVersion() {
return version;
}
/**
* Returns the value of serialNumber field of the structure.
* @return serialNumber
*/
public BigInteger getSerialNumber() {
return serialNumber;
}
/**
* Returns the value of signature field of the structure.
* @return signature
*/
public AlgorithmIdentifier getSignature() {
return signature;
}
/**
* Returns the value of issuer field of the structure.
* @return issuer
*/
public Name getIssuer() {
return issuer;
}
/**
* Returns the value of validity field of the structure.
* @return validity
*/
public Validity getValidity() {
return validity;
}
/**
* Returns the value of subject field of the structure.
* @return subject
*/
public Name getSubject() {
return subject;
}
/**
* Returns the value of subjectPublicKeyInfo field of the structure.
* @return subjectPublicKeyInfo
*/
public SubjectPublicKeyInfo getSubjectPublicKeyInfo() {
return subjectPublicKeyInfo;
}
/**
* Returns the value of issuerUniqueID field of the structure.
* @return issuerUniqueID
*/
public boolean[] getIssuerUniqueID() {
return issuerUniqueID;
}
/**
* Returns the value of subjectUniqueID field of the structure.
* @return subjectUniqueID
*/
public boolean[] getSubjectUniqueID() {
return subjectUniqueID;
}
/**
* Returns the value of extensions field of the structure.
* @return extensions
*/
public Extensions getExtensions() {
return extensions;
}
/**
* Returns ASN.1 encoded form of this X.509 TBSCertificate value.
* @return a byte array containing ASN.1 encode form.
*/
public byte[] getEncoded() {
if (encoding == null) {
encoding = ASN1.encode(this);
}
return encoding;
}
/**
* Places the string representation into the StringBuffer object.
*/
public void dumpValue(StringBuffer buffer) {
buffer.append('[');
buffer.append("\n Version: V").append(version+1);
buffer.append("\n Subject: ")
.append(subject.getName(X500Principal.RFC2253));
buffer.append("\n Signature Algorithm: ");
signature.dumpValue(buffer);
buffer.append("\n Key: ");
buffer.append(subjectPublicKeyInfo.getPublicKey().toString());
buffer.append("\n Validity: [From: ");
buffer.append(validity.getNotBefore());
buffer.append("\n To: ");
buffer.append(validity.getNotAfter()).append(']');
buffer.append("\n Issuer: ");
buffer.append(issuer.getName(X500Principal.RFC2253));
buffer.append("\n Serial Number: ");
buffer.append(serialNumber);
if (issuerUniqueID != null) {
buffer.append("\n Issuer Id: ");
for (int i=0; i<issuerUniqueID.length; i++) {
buffer.append(issuerUniqueID[i] ? '1' : '0');
}
}
if (subjectUniqueID != null) {
buffer.append("\n Subject Id: ");
for (int i=0; i<subjectUniqueID.length; i++) {
buffer.append(subjectUniqueID[i] ? '1' : '0');
}
}
if (extensions != null) {
buffer.append("\n\n Extensions: ");
buffer.append("[\n");
extensions.dumpValue(buffer, " ");
buffer.append(" ]");
}
buffer.append("\n]");
}
/**
* X.509 TBSCertificate encoder/decoder.
*/
public static final ASN1Sequence ASN1 = new ASN1Sequence(new ASN1Type[] {
new ASN1Explicit(0, ASN1Integer.getInstance()), ASN1Integer.getInstance(),
AlgorithmIdentifier.ASN1, Name.ASN1,
Validity.ASN1, Name.ASN1, SubjectPublicKeyInfo.ASN1,
new ASN1Implicit(1, ASN1BitString.getInstance()),
new ASN1Implicit(2, ASN1BitString.getInstance()),
new ASN1Explicit(3, Extensions.ASN1)}) {
{
setDefault(new byte[] {0}, 0);
setOptional(7);
setOptional(8);
setOptional(9);
}
protected Object getDecodedObject(BerInputStream in) {
Object[] values = (Object[]) in.content;
boolean[] issuerUniqueID = (values[7] == null)
? null : ((BitString) values[7]).toBooleanArray();
boolean[] subjectUniqueID = (values[8] == null)
? null : ((BitString) values[8]).toBooleanArray();
return new TBSCertificate(
ASN1Integer.toIntValue(values[0]),
new BigInteger((byte[]) values[1]),
(AlgorithmIdentifier) values[2],
(Name) values[3],
(Validity) values[4],
(Name) values[5],
(SubjectPublicKeyInfo) values[6],
issuerUniqueID,
subjectUniqueID,
(Extensions) values[9],
in.getEncoded()
);
}
protected void getValues(Object object, Object[] values) {
TBSCertificate tbs = (TBSCertificate) object;
values[0] = ASN1Integer.fromIntValue(tbs.version);
values[1] = tbs.serialNumber.toByteArray();
values[2] = tbs.signature;
values[3] = tbs.issuer;
values[4] = tbs.validity;
values[5] = tbs.subject;
values[6] = tbs.subjectPublicKeyInfo;
if (tbs.issuerUniqueID != null) {
values[7] = new BitString(tbs.issuerUniqueID);
}
if (tbs.subjectUniqueID != null) {
values[8] = new BitString(tbs.subjectUniqueID);
}
values[9] = tbs.extensions;
}
};
}