1 /* 2 * Copyright (C) 2015 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 package org.conscrypt.ct; 18 19 import java.io.ByteArrayInputStream; 20 import java.io.ByteArrayOutputStream; 21 import java.io.InputStream; 22 import java.io.OutputStream; 23 import org.conscrypt.Internal; 24 25 /** 26 * SignedCertificateTimestamp structure, as defined by RFC6962 Section 3.2. 27 */ 28 @Internal 29 public class SignedCertificateTimestamp { 30 public enum Version { 31 V1 32 }; 33 34 public enum SignatureType { 35 CERTIFICATE_TIMESTAMP, 36 TREE_HASH 37 }; 38 39 public enum Origin { 40 EMBEDDED, 41 TLS_EXTENSION, 42 OCSP_RESPONSE 43 }; 44 45 private final Version version; 46 private final byte[] logId; 47 private final long timestamp; 48 private final byte[] extensions; 49 private final DigitallySigned signature; 50 51 // origin is implied from the SCT's source and is not encoded in it, 52 // and affects the verification process. 53 private final Origin origin; 54 SignedCertificateTimestamp(Version version, byte[] logId, long timestamp, byte[] extensions, DigitallySigned signature, Origin origin)55 public SignedCertificateTimestamp(Version version, byte[] logId, 56 long timestamp, byte[] extensions, 57 DigitallySigned signature, Origin origin) { 58 this.version = version; 59 this.logId = logId; 60 this.timestamp = timestamp; 61 this.extensions = extensions; 62 this.signature = signature; 63 this.origin = origin; 64 } 65 getVersion()66 public Version getVersion() { 67 return version; 68 } getLogID()69 public byte[] getLogID() { 70 return logId; 71 } getTimestamp()72 public long getTimestamp() { 73 return timestamp; 74 } getExtensions()75 public byte[] getExtensions() { 76 return extensions; 77 } getSignature()78 public DigitallySigned getSignature() { 79 return signature; 80 } getOrigin()81 public Origin getOrigin() { 82 return origin; 83 } 84 85 /** 86 * Decode a TLS encoded SignedCertificateTimestamp structure. 87 */ decode(InputStream input, Origin origin)88 public static SignedCertificateTimestamp decode(InputStream input, Origin origin) 89 throws SerializationException { 90 int version = Serialization.readNumber(input, CTConstants.VERSION_LENGTH); 91 if (version != Version.V1.ordinal()) { 92 throw new SerializationException("Unsupported SCT version " + version); 93 } 94 95 return new SignedCertificateTimestamp( 96 Version.V1, 97 Serialization.readFixedBytes(input, CTConstants.LOGID_LENGTH), 98 Serialization.readLong(input, CTConstants.TIMESTAMP_LENGTH), 99 Serialization.readVariableBytes(input, CTConstants.EXTENSIONS_LENGTH_BYTES), 100 DigitallySigned.decode(input), 101 origin 102 ); 103 } 104 105 /** 106 * Decode a TLS encoded SignedCertificateTimestamp structure. 107 */ decode(byte[] input, Origin origin)108 public static SignedCertificateTimestamp decode(byte[] input, Origin origin) 109 throws SerializationException { 110 return decode(new ByteArrayInputStream(input), origin); 111 } 112 113 /** 114 * TLS encode the signed part of the SCT, as described by RFC6962 section 3.2. 115 */ encodeTBS(OutputStream output, CertificateEntry certEntry)116 public void encodeTBS(OutputStream output, CertificateEntry certEntry) 117 throws SerializationException { 118 Serialization.writeNumber(output, version.ordinal(), CTConstants.VERSION_LENGTH); 119 Serialization.writeNumber(output, SignatureType.CERTIFICATE_TIMESTAMP.ordinal(), 120 CTConstants.SIGNATURE_TYPE_LENGTH); 121 Serialization.writeNumber(output, timestamp, CTConstants.TIMESTAMP_LENGTH); 122 certEntry.encode(output); 123 Serialization.writeVariableBytes(output, extensions, CTConstants.EXTENSIONS_LENGTH_BYTES); 124 } 125 126 /** 127 * TLS encode the signed part of the SCT, as described by RFC6962 section 3.2. 128 */ encodeTBS(CertificateEntry certEntry)129 public byte[] encodeTBS(CertificateEntry certEntry) 130 throws SerializationException { 131 ByteArrayOutputStream output = new ByteArrayOutputStream(); 132 encodeTBS(output, certEntry); 133 return output.toByteArray(); 134 } 135 } 136 137