Home | History | Annotate | Download | only in pkcs7
      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 Boris Kuznetsov
     20 * @version $Revision$
     21 */
     22 package org.apache.harmony.security.pkcs7;
     23 
     24 import java.io.IOException;
     25 import java.math.BigInteger;
     26 import java.util.List;
     27 import javax.security.auth.x500.X500Principal;
     28 import org.apache.harmony.security.asn1.ASN1Implicit;
     29 import org.apache.harmony.security.asn1.ASN1Integer;
     30 import org.apache.harmony.security.asn1.ASN1OctetString;
     31 import org.apache.harmony.security.asn1.ASN1Sequence;
     32 import org.apache.harmony.security.asn1.ASN1SetOf;
     33 import org.apache.harmony.security.asn1.ASN1Type;
     34 import org.apache.harmony.security.asn1.BerInputStream;
     35 import org.apache.harmony.security.x501.AttributeTypeAndValue;
     36 import org.apache.harmony.security.x501.Name;
     37 import org.apache.harmony.security.x509.AlgorithmIdentifier;
     38 
     39 
     40 /**
     41  * As defined in PKCS #7: Cryptographic Message Syntax Standard
     42  * (http://www.ietf.org/rfc/rfc2315.txt)
     43  *
     44  * SignerInfo ::= SEQUENCE {
     45  *   version Version,
     46  *   issuerAndSerialNumber IssuerAndSerialNumber,
     47  *   digestAlgorithm DigestAlgorithmIdentifier,
     48  *   authenticatedAttributes
     49  *     [0] IMPLICIT Attributes OPTIONAL,
     50  *   digestEncryptionAlgorithm
     51  *     DigestEncryptionAlgorithmIdentifier,
     52  *   encryptedDigest EncryptedDigest,
     53  *   unauthenticatedAttributes
     54  *     [1] IMPLICIT Attributes OPTIONAL
     55  *  }
     56  *
     57  */
     58 public class SignerInfo {
     59 
     60     private int version;
     61     private X500Principal issuer;
     62     private BigInteger serialNumber;
     63 
     64     private AlgorithmIdentifier digestAlgorithm;
     65     private AuthenticatedAttributes authenticatedAttributes;
     66     private AlgorithmIdentifier digestEncryptionAlgorithm;
     67     private byte[] encryptedDigest;
     68     private List unauthenticatedAttributes;
     69 
     70     public SignerInfo(int version,
     71             Object[] issuerAndSerialNumber,
     72             AlgorithmIdentifier digestAlgorithm,
     73             AuthenticatedAttributes authenticatedAttributes,
     74             AlgorithmIdentifier digestEncryptionAlgorithm,
     75             byte[] encryptedDigest,
     76             List unauthenticatedAttributes
     77             ) {
     78         this.version = version;
     79         this.issuer = ((Name)issuerAndSerialNumber[0]).getX500Principal();
     80         // BEGIN android-changed
     81         this.serialNumber = ASN1Integer.toBigIntegerValue(issuerAndSerialNumber[1]);
     82         // END android-changed
     83         this.digestAlgorithm = digestAlgorithm;
     84         this.authenticatedAttributes = authenticatedAttributes;
     85         this.digestEncryptionAlgorithm = digestEncryptionAlgorithm;
     86         this.encryptedDigest = encryptedDigest;
     87         this.unauthenticatedAttributes = unauthenticatedAttributes;
     88     }
     89 
     90     public X500Principal getIssuer() {
     91         return issuer;
     92     }
     93 
     94     public BigInteger getSerialNumber() {
     95         return serialNumber;
     96     }
     97 
     98     public String getDigestAlgorithm() {
     99         return digestAlgorithm.getAlgorithm();
    100     }
    101 
    102     public String getdigestAlgorithm() {
    103         return digestAlgorithm.getAlgorithm();
    104     }
    105 
    106     public String getDigestEncryptionAlgorithm() {
    107         return digestEncryptionAlgorithm.getAlgorithm();
    108     }
    109 
    110     public List getAuthenticatedAttributes() {
    111         if (authenticatedAttributes == null) {
    112             return null;
    113         }
    114         return authenticatedAttributes.getAttributes();
    115     }
    116 
    117     public byte[] getEncodedAuthenticatedAttributes() {
    118         if (authenticatedAttributes == null) {
    119             return null;
    120         }
    121         return authenticatedAttributes.getEncoded();
    122     }
    123 
    124     public byte[] getEncryptedDigest() {
    125         return encryptedDigest;
    126     }
    127 
    128 
    129     public String toString() {
    130         StringBuilder res = new StringBuilder();
    131         res.append("-- SignerInfo:");
    132         res.append("\n version : ");
    133         res.append(version);
    134         res.append("\nissuerAndSerialNumber:  ");
    135         res.append(issuer);
    136         res.append("   ");
    137         res.append(serialNumber);
    138         res.append("\ndigestAlgorithm:  ");
    139         res.append(digestAlgorithm.toString());
    140         res.append("\nauthenticatedAttributes:  ");
    141         if (authenticatedAttributes != null) {
    142             res.append(authenticatedAttributes.toString());
    143         }
    144         res.append("\ndigestEncryptionAlgorithm: ");
    145         res.append(digestEncryptionAlgorithm.toString());
    146         res.append("\nunauthenticatedAttributes: ");
    147         if (unauthenticatedAttributes != null) {
    148             res.append(unauthenticatedAttributes.toString());
    149         }
    150         res.append("\n-- SignerInfo End\n");
    151         return res.toString();
    152     }
    153 
    154 
    155     public static final ASN1Sequence ISSUER_AND_SERIAL_NUMBER =
    156             new ASN1Sequence(new ASN1Type[] {
    157                 Name.ASN1,                       // issuer
    158                 ASN1Integer.getInstance(),       // serialNumber
    159             })
    160         {
    161             // method to encode
    162             public void getValues(Object object, Object[] values) {
    163                 Object [] issAndSerial = (Object[])object;
    164                 values[0] = issAndSerial[0];
    165                 values[1] = issAndSerial[1];
    166         }
    167     };
    168 
    169     public static final ASN1Sequence ASN1 =
    170         new ASN1Sequence(new ASN1Type[] {
    171                 ASN1Integer.getInstance(),         //version
    172                 ISSUER_AND_SERIAL_NUMBER,
    173                 AlgorithmIdentifier.ASN1,           //digestAlgorithm
    174                 new ASN1Implicit(0, AuthenticatedAttributes.ASN1),//authenticatedAttributes
    175                 AlgorithmIdentifier.ASN1,            //digestEncryptionAlgorithm
    176                 ASN1OctetString.getInstance(),       //encryptedDigest
    177                  new ASN1Implicit(1, new ASN1SetOf(
    178                          AttributeTypeAndValue.ASN1)),//unauthenticatedAttributes
    179                 })  {
    180         {
    181             setOptional(3); // authenticatedAttributes is optional
    182             setOptional(6); // unauthenticatedAttributes is optional
    183         }
    184 
    185         protected void getValues(Object object, Object[] values) {
    186             SignerInfo si = (SignerInfo) object;
    187             values[0] = new byte[] {(byte)si.version};
    188             try {
    189                 values[1] = new Object[] { new Name(si.issuer.getName()),
    190                         si.serialNumber.toByteArray() };
    191             } catch (IOException e) {
    192                 // The exception is never thrown, because si.issuer
    193                 // is created using Name.getX500Principal().
    194                 // Throw a RuntimeException just to be safe.
    195                 throw new RuntimeException("Failed to encode issuer name", e);
    196             }
    197             values[2] = si.digestAlgorithm;
    198             values[3] = si.authenticatedAttributes;
    199             values[4] = si.digestEncryptionAlgorithm;
    200             values[5] = si.encryptedDigest;
    201             values[6] = si.unauthenticatedAttributes;
    202         }
    203 
    204         protected Object getDecodedObject(BerInputStream in) {
    205             Object[] values = (Object[]) in.content;
    206             return new SignerInfo(
    207                         ASN1Integer.toIntValue(values[0]),
    208                         (Object[]) values[1],
    209                         (AlgorithmIdentifier) values[2],
    210                         (AuthenticatedAttributes) values[3],
    211                         (AlgorithmIdentifier) values[4],
    212                         (byte[]) values[5],
    213                         (List) values[6]
    214                     );
    215         }
    216    };
    217 }
    218