Home | History | Annotate | Download | only in ct
      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.InputStream;
     21 import org.conscrypt.Internal;
     22 
     23 /**
     24  * DigitallySigned structure, as defined by RFC5246 Section 4.7.
     25  *
     26  * @hide
     27  */
     28 @Internal
     29 public class DigitallySigned {
     30     public enum HashAlgorithm {
     31         NONE,
     32         MD5,
     33         SHA1,
     34         SHA224,
     35         SHA256,
     36         SHA384,
     37         SHA512;
     38 
     39         private static HashAlgorithm[] values = values();
     40         public static HashAlgorithm valueOf(int ord) {
     41             try {
     42                 return values[ord];
     43             } catch (IndexOutOfBoundsException e) {
     44                 throw new IllegalArgumentException("Invalid hash algorithm " + ord, e);
     45             }
     46         }
     47     }
     48 
     49     public enum SignatureAlgorithm {
     50         ANONYMOUS,
     51         RSA,
     52         DSA,
     53         ECDSA;
     54 
     55         private static SignatureAlgorithm[] values = values();
     56         public static SignatureAlgorithm valueOf(int ord) {
     57             try {
     58                 return values[ord];
     59             } catch (IndexOutOfBoundsException e) {
     60                 throw new IllegalArgumentException("Invalid signature algorithm " + ord, e);
     61             }
     62         }
     63     }
     64 
     65     private final HashAlgorithm hashAlgorithm;
     66     private final SignatureAlgorithm signatureAlgorithm;
     67     private final byte[] signature;
     68 
     69     public DigitallySigned(HashAlgorithm hashAlgorithm,
     70                            SignatureAlgorithm signatureAlgorithm,
     71                            byte[] signature) {
     72         this.hashAlgorithm = hashAlgorithm;
     73         this.signatureAlgorithm = signatureAlgorithm;
     74         this.signature = signature;
     75     }
     76 
     77     public DigitallySigned(int hashAlgorithm,
     78                            int signatureAlgorithm,
     79                            byte[] signature) {
     80         this(
     81             HashAlgorithm.valueOf(hashAlgorithm),
     82             SignatureAlgorithm.valueOf(signatureAlgorithm),
     83             signature
     84         );
     85     }
     86 
     87     public HashAlgorithm getHashAlgorithm() {
     88         return hashAlgorithm;
     89     }
     90     public SignatureAlgorithm getSignatureAlgorithm() {
     91         return signatureAlgorithm;
     92     }
     93     public byte[] getSignature() {
     94         return signature;
     95     }
     96 
     97     /**
     98      * Get the name of the hash and signature combination.
     99      * The result can be used to as the argument to {@link java.security.Signature#getInstance}.
    100      */
    101     public String getAlgorithm() {
    102         return String.format("%swith%s", hashAlgorithm, signatureAlgorithm);
    103     }
    104 
    105     /**
    106      * Decode a TLS encoded DigitallySigned structure.
    107      */
    108     public static DigitallySigned decode(InputStream input)
    109         throws SerializationException {
    110         try {
    111             return new DigitallySigned(
    112                 Serialization.readNumber(input, CTConstants.HASH_ALGORITHM_LENGTH),
    113                 Serialization.readNumber(input, CTConstants.SIGNATURE_ALGORITHM_LENGTH),
    114                 Serialization.readVariableBytes(input, CTConstants.SIGNATURE_LENGTH_BYTES)
    115             );
    116         } catch (IllegalArgumentException e) {
    117             throw new SerializationException(e);
    118         }
    119     }
    120 
    121     /**
    122      * Decode a TLS encoded DigitallySigned structure.
    123      */
    124     public static DigitallySigned decode(byte[] input)
    125             throws SerializationException {
    126         return decode(new ByteArrayInputStream(input));
    127     }
    128 }
    129 
    130 
    131