| /* |
| * 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 final 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 */ |
| private byte[] encoding; |
| |
| 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; |
| } |
| |
| 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. |
| */ |
| public int getVersion() { |
| return version; |
| } |
| |
| /** |
| * Returns the value of serialNumber field of the structure. |
| */ |
| public BigInteger getSerialNumber() { |
| return serialNumber; |
| } |
| |
| /** |
| * Returns the value of signature field of the structure. |
| */ |
| public AlgorithmIdentifier getSignature() { |
| return signature; |
| } |
| |
| /** |
| * Returns the value of issuer field of the structure. |
| */ |
| public Name getIssuer() { |
| return issuer; |
| } |
| |
| /** |
| * Returns the value of validity field of the structure. |
| */ |
| public Validity getValidity() { |
| return validity; |
| } |
| |
| /** |
| * Returns the value of subject field of the structure. |
| */ |
| public Name getSubject() { |
| return subject; |
| } |
| |
| /** |
| * Returns the value of subjectPublicKeyInfo field of the structure. |
| */ |
| public SubjectPublicKeyInfo getSubjectPublicKeyInfo() { |
| return subjectPublicKeyInfo; |
| } |
| |
| /** |
| * Returns the value of issuerUniqueID field of the structure. |
| */ |
| public boolean[] getIssuerUniqueID() { |
| return issuerUniqueID; |
| } |
| |
| /** |
| * Returns the value of subjectUniqueID field of the structure. |
| */ |
| public boolean[] getSubjectUniqueID() { |
| return subjectUniqueID; |
| } |
| |
| /** |
| * Returns the value of extensions field of the structure. |
| */ |
| public Extensions getExtensions() { |
| return extensions; |
| } |
| |
| /** |
| * Returns ASN.1 encoded form of this X.509 TBSCertificate value. |
| */ |
| public byte[] getEncoded() { |
| if (encoding == null) { |
| encoding = ASN1.encode(this); |
| } |
| return encoding; |
| } |
| |
| public void dumpValue(StringBuilder sb) { |
| sb.append('['); |
| sb.append("\n Version: V").append(version+1); |
| sb.append("\n Subject: ").append(subject.getName(X500Principal.RFC2253)); |
| sb.append("\n Signature Algorithm: "); |
| signature.dumpValue(sb); |
| sb.append("\n Key: ").append(subjectPublicKeyInfo.getPublicKey().toString()); |
| sb.append("\n Validity: [From: ").append(validity.getNotBefore()); |
| sb.append("\n To: ").append(validity.getNotAfter()).append(']'); |
| sb.append("\n Issuer: ").append(issuer.getName(X500Principal.RFC2253)); |
| sb.append("\n Serial Number: ").append(serialNumber); |
| if (issuerUniqueID != null) { |
| sb.append("\n Issuer Id: "); |
| for (boolean b : issuerUniqueID) { |
| sb.append(b ? '1' : '0'); |
| } |
| } |
| if (subjectUniqueID != null) { |
| sb.append("\n Subject Id: "); |
| for (boolean b : subjectUniqueID) { |
| sb.append(b ? '1' : '0'); |
| } |
| } |
| if (extensions != null) { |
| sb.append("\n\n Extensions: "); |
| sb.append("[\n"); |
| extensions.dumpValue(sb, " "); |
| sb.append(" ]"); |
| } |
| sb.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); |
| } |
| |
| @Override 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() |
| ); |
| } |
| |
| @Override 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; |
| } |
| }; |
| } |