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 23 package org.apache.harmony.security.x509; 24 25 import org.apache.harmony.security.asn1.ASN1BitString; 26 import org.apache.harmony.security.asn1.ASN1Sequence; 27 import org.apache.harmony.security.asn1.ASN1Type; 28 import org.apache.harmony.security.asn1.BerInputStream; 29 import org.apache.harmony.security.asn1.BitString; 30 import org.apache.harmony.security.utils.Array; 31 32 /** 33 * The class encapsulates the ASN.1 DER encoding/decoding work 34 * with the X.509 certificate. Its ASN notation is as follows 35 * (as specified in RFC 3280 - 36 * Internet X.509 Public Key Infrastructure. 37 * Certificate and Certificate Revocation List (CRL) Profile. 38 * http://www.ietf.org/rfc/rfc3280.txt): 39 * 40 * <pre> 41 * Certificate ::= SEQUENCE { 42 * tbsCertificate TBSCertificate, 43 * signatureAlgorithm AlgorithmIdentifier, 44 * signatureValue BIT STRING 45 * } 46 * </pre> 47 */ 48 public final class Certificate { 49 /** the value of tbsCertificate field of the structure */ 50 private final TBSCertificate tbsCertificate; 51 /** the value of signatureAlgorithm field of the structure */ 52 private final AlgorithmIdentifier signatureAlgorithm; 53 /** the value of signatureValue field of the structure */ 54 private final byte[] signatureValue; 55 /** the ASN.1 encoded form of Certificate */ 56 private byte[] encoding; 57 58 public Certificate(TBSCertificate tbsCertificate, 59 AlgorithmIdentifier signatureAlgorithm, 60 byte[] signatureValue) { 61 this.tbsCertificate = tbsCertificate; 62 this.signatureAlgorithm = signatureAlgorithm; 63 this.signatureValue = new byte[signatureValue.length]; 64 System.arraycopy(signatureValue, 0, this.signatureValue, 0, 65 signatureValue.length); 66 } 67 68 private Certificate(TBSCertificate tbsCertificate, 69 AlgorithmIdentifier signatureAlgorithm, 70 byte[] signatureValue, byte[] encoding) { 71 this(tbsCertificate, signatureAlgorithm, signatureValue); 72 this.encoding = encoding; 73 } 74 75 /** 76 * Returns the value of tbsCertificate field of the structure. 77 */ 78 public TBSCertificate getTbsCertificate() { 79 return tbsCertificate; 80 } 81 82 /** 83 * Returns the value of signatureValue field of the structure. 84 */ 85 public byte[] getSignatureValue() { 86 return signatureValue.clone(); 87 } 88 89 @Override public String toString() { 90 StringBuilder result = new StringBuilder(); 91 result.append("X.509 Certificate:\n[\n"); 92 tbsCertificate.dumpValue(result); 93 result.append("\n Algorithm: ["); 94 signatureAlgorithm.dumpValue(result); 95 result.append(']'); 96 result.append("\n Signature Value:\n"); 97 result.append(Array.toString(signatureValue, "")); 98 result.append(']'); 99 return result.toString(); 100 } 101 102 /** 103 * Returns ASN.1 encoded form of this X.509 TBSCertificate value. 104 */ 105 public byte[] getEncoded() { 106 if (encoding == null) { 107 encoding = Certificate.ASN1.encode(this); 108 } 109 return encoding; 110 } 111 112 /** 113 * X.509 Certificate encoder/decoder. 114 */ 115 public static final ASN1Sequence ASN1 = 116 new ASN1Sequence(new ASN1Type[] 117 {TBSCertificate.ASN1, AlgorithmIdentifier.ASN1, ASN1BitString.getInstance()}) { 118 119 @Override protected Object getDecodedObject(BerInputStream in) { 120 Object[] values = (Object[]) in.content; 121 return new Certificate( 122 (TBSCertificate) values[0], 123 (AlgorithmIdentifier) values[1], 124 ((BitString) values[2]).bytes, // FIXME keep as BitString object 125 in.getEncoded()); 126 } 127 128 @Override protected void getValues(Object object, Object[] values) { 129 Certificate cert = (Certificate) object; 130 values[0] = cert.tbsCertificate; 131 values[1] = cert.signatureAlgorithm; 132 values[2] = new BitString(cert.signatureValue, 0); 133 } 134 }; 135 } 136