1/* 2 * Licensed to the Apache Software Foundation (ASF) under one or more 3 * contributor license agreements. See the NOTICE file distributed with 4 * this work for additional information regarding copyright ownership. 5 * The ASF licenses this file to You under the Apache License, Version 2.0 6 * (the "License"); you may not use this file except in compliance with 7 * the License. You may obtain a copy of the License at 8 * 9 * http://www.apache.org/licenses/LICENSE-2.0 10 * 11 * Unless required by applicable law or agreed to in writing, software 12 * distributed under the License is distributed on an "AS IS" BASIS, 13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 * See the License for the specific language governing permissions and 15 * limitations under the License. 16 */ 17 18/** 19* @author Alexander Y. Kleymenov 20* @version $Revision$ 21*/ 22 23package org.apache.harmony.security.x509; 24 25import java.math.BigInteger; 26import javax.security.auth.x500.X500Principal; 27import org.apache.harmony.security.asn1.ASN1BitString; 28import org.apache.harmony.security.asn1.ASN1Explicit; 29import org.apache.harmony.security.asn1.ASN1Implicit; 30import org.apache.harmony.security.asn1.ASN1Integer; 31import org.apache.harmony.security.asn1.ASN1Sequence; 32import org.apache.harmony.security.asn1.ASN1Type; 33import org.apache.harmony.security.asn1.BerInputStream; 34import org.apache.harmony.security.asn1.BitString; 35import org.apache.harmony.security.x501.Name; 36 37/** 38 * The class encapsulates the ASN.1 DER encoding/decoding work 39 * with TBSCertificate structure which is the part of X.509 certificate 40 * (as specified in RFC 3280 - 41 * Internet X.509 Public Key Infrastructure. 42 * Certificate and Certificate Revocation List (CRL) Profile. 43 * http://www.ietf.org/rfc/rfc3280.txt): 44 * 45 * <pre> 46 * TBSCertificate ::= SEQUENCE { 47 * version [0] EXPLICIT Version DEFAULT v1, 48 * serialNumber CertificateSerialNumber, 49 * signature AlgorithmIdentifier, 50 * issuer Name, 51 * validity Validity, 52 * subject Name, 53 * subjectPublicKeyInfo SubjectPublicKeyInfo, 54 * issuerUniqueID [1] IMPLICIT UniqueIdentifier OPTIONAL, 55 * -- If present, version MUST be v2 or v3 56 * subjectUniqueID [2] IMPLICIT UniqueIdentifier OPTIONAL, 57 * -- If present, version MUST be v2 or v3 58 * extensions [3] EXPLICIT Extensions OPTIONAL 59 * -- If present, version MUST be v3 60 * } 61 * </pre> 62 */ 63public final class TBSCertificate { 64 65 /** the value of version field of the structure */ 66 private final int version; 67 /** the value of serialNumber field of the structure */ 68 private final BigInteger serialNumber; 69 /** the value of signature field of the structure */ 70 private final AlgorithmIdentifier signature; 71 /** the value of issuer field of the structure */ 72 private final Name issuer; 73 /** the value of validity field of the structure */ 74 private final Validity validity; 75 /** the value of subject field of the structure */ 76 private final Name subject; 77 /** the value of subjectPublicKeyInfo field of the structure */ 78 private final SubjectPublicKeyInfo subjectPublicKeyInfo; 79 /** the value of issuerUniqueID field of the structure */ 80 private final boolean[] issuerUniqueID; 81 /** the value of subjectUniqueID field of the structure */ 82 private final boolean[] subjectUniqueID; 83 /** the value of extensions field of the structure */ 84 private final Extensions extensions; 85 /** the ASN.1 encoded form of TBSCertificate */ 86 private byte[] encoding; 87 88 public TBSCertificate(int version, BigInteger serialNumber, 89 AlgorithmIdentifier signature, Name issuer, 90 Validity validity, Name subject, 91 SubjectPublicKeyInfo subjectPublicKeyInfo, 92 boolean[] issuerUniqueID, boolean[] subjectUniqueID, 93 Extensions extensions) { 94 this.version = version; 95 this.serialNumber = serialNumber; 96 this.signature = signature; 97 this.issuer = issuer; 98 this.validity = validity; 99 this.subject = subject; 100 this.subjectPublicKeyInfo = subjectPublicKeyInfo; 101 this.issuerUniqueID = issuerUniqueID; 102 this.subjectUniqueID = subjectUniqueID; 103 this.extensions = extensions; 104 } 105 106 private TBSCertificate(int version, BigInteger serialNumber, 107 AlgorithmIdentifier signature, Name issuer, 108 Validity validity, Name subject, 109 SubjectPublicKeyInfo subjectPublicKeyInfo, 110 boolean[] issuerUniqueID, boolean[] subjectUniqueID, 111 Extensions extensions, byte[] encoding) { 112 this(version, serialNumber, signature, issuer, validity, subject, 113 subjectPublicKeyInfo, issuerUniqueID, subjectUniqueID, extensions); 114 this.encoding = encoding; 115 } 116 117 /** 118 * Returns the value of version field of the structure. 119 */ 120 public int getVersion() { 121 return version; 122 } 123 124 /** 125 * Returns the value of serialNumber field of the structure. 126 */ 127 public BigInteger getSerialNumber() { 128 return serialNumber; 129 } 130 131 /** 132 * Returns the value of signature field of the structure. 133 */ 134 public AlgorithmIdentifier getSignature() { 135 return signature; 136 } 137 138 /** 139 * Returns the value of issuer field of the structure. 140 */ 141 public Name getIssuer() { 142 return issuer; 143 } 144 145 /** 146 * Returns the value of validity field of the structure. 147 */ 148 public Validity getValidity() { 149 return validity; 150 } 151 152 /** 153 * Returns the value of subject field of the structure. 154 */ 155 public Name getSubject() { 156 return subject; 157 } 158 159 /** 160 * Returns the value of subjectPublicKeyInfo field of the structure. 161 */ 162 public SubjectPublicKeyInfo getSubjectPublicKeyInfo() { 163 return subjectPublicKeyInfo; 164 } 165 166 /** 167 * Returns the value of issuerUniqueID field of the structure. 168 */ 169 public boolean[] getIssuerUniqueID() { 170 return issuerUniqueID; 171 } 172 173 /** 174 * Returns the value of subjectUniqueID field of the structure. 175 */ 176 public boolean[] getSubjectUniqueID() { 177 return subjectUniqueID; 178 } 179 180 /** 181 * Returns the value of extensions field of the structure. 182 */ 183 public Extensions getExtensions() { 184 return extensions; 185 } 186 187 /** 188 * Returns ASN.1 encoded form of this X.509 TBSCertificate value. 189 */ 190 public byte[] getEncoded() { 191 if (encoding == null) { 192 encoding = ASN1.encode(this); 193 } 194 return encoding; 195 } 196 197 public void dumpValue(StringBuilder sb) { 198 sb.append('['); 199 sb.append("\n Version: V").append(version+1); 200 sb.append("\n Subject: ").append(subject.getName(X500Principal.RFC2253)); 201 sb.append("\n Signature Algorithm: "); 202 signature.dumpValue(sb); 203 sb.append("\n Key: ").append(subjectPublicKeyInfo.getPublicKey().toString()); 204 sb.append("\n Validity: [From: ").append(validity.getNotBefore()); 205 sb.append("\n To: ").append(validity.getNotAfter()).append(']'); 206 sb.append("\n Issuer: ").append(issuer.getName(X500Principal.RFC2253)); 207 sb.append("\n Serial Number: ").append(serialNumber); 208 if (issuerUniqueID != null) { 209 sb.append("\n Issuer Id: "); 210 for (boolean b : issuerUniqueID) { 211 sb.append(b ? '1' : '0'); 212 } 213 } 214 if (subjectUniqueID != null) { 215 sb.append("\n Subject Id: "); 216 for (boolean b : subjectUniqueID) { 217 sb.append(b ? '1' : '0'); 218 } 219 } 220 if (extensions != null) { 221 sb.append("\n\n Extensions: "); 222 sb.append("[\n"); 223 extensions.dumpValue(sb, " "); 224 sb.append(" ]"); 225 } 226 sb.append("\n]"); 227 } 228 229 /** 230 * X.509 TBSCertificate encoder/decoder. 231 */ 232 public static final ASN1Sequence ASN1 = new ASN1Sequence(new ASN1Type[] { 233 new ASN1Explicit(0, ASN1Integer.getInstance()), ASN1Integer.getInstance(), 234 AlgorithmIdentifier.ASN1, Name.ASN1, 235 Validity.ASN1, Name.ASN1, SubjectPublicKeyInfo.ASN1, 236 new ASN1Implicit(1, ASN1BitString.getInstance()), 237 new ASN1Implicit(2, ASN1BitString.getInstance()), 238 new ASN1Explicit(3, Extensions.ASN1)}) { 239 { 240 setDefault(new byte[] {0}, 0); 241 setOptional(7); 242 setOptional(8); 243 setOptional(9); 244 } 245 246 @Override protected Object getDecodedObject(BerInputStream in) { 247 Object[] values = (Object[]) in.content; 248 249 boolean[] issuerUniqueID = (values[7] == null) 250 ? null : ((BitString) values[7]).toBooleanArray(); 251 boolean[] subjectUniqueID = (values[8] == null) 252 ? null : ((BitString) values[8]).toBooleanArray(); 253 return new TBSCertificate( 254 ASN1Integer.toIntValue(values[0]), 255 new BigInteger((byte[]) values[1]), 256 (AlgorithmIdentifier) values[2], 257 (Name) values[3], 258 (Validity) values[4], 259 (Name) values[5], 260 (SubjectPublicKeyInfo) values[6], 261 issuerUniqueID, 262 subjectUniqueID, 263 (Extensions) values[9], 264 in.getEncoded() 265 ); 266 } 267 268 @Override protected void getValues(Object object, Object[] values) { 269 TBSCertificate tbs = (TBSCertificate) object; 270 values[0] = ASN1Integer.fromIntValue(tbs.version); 271 values[1] = tbs.serialNumber.toByteArray(); 272 values[2] = tbs.signature; 273 values[3] = tbs.issuer; 274 values[4] = tbs.validity; 275 values[5] = tbs.subject; 276 values[6] = tbs.subjectPublicKeyInfo; 277 if (tbs.issuerUniqueID != null) { 278 values[7] = new BitString(tbs.issuerUniqueID); 279 } 280 if (tbs.subjectUniqueID != null) { 281 values[8] = new BitString(tbs.subjectUniqueID); 282 } 283 values[9] = tbs.extensions; 284 } 285 }; 286} 287