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 public final class SignerInfo {
     58     private final int version;
     59     private final X500Principal issuer;
     60     private final BigInteger serialNumber;
     61     private final AlgorithmIdentifier digestAlgorithm;
     62     private final AuthenticatedAttributes authenticatedAttributes;
     63     private final AlgorithmIdentifier digestEncryptionAlgorithm;
     64     private final byte[] encryptedDigest;
     65     private final List<?> unauthenticatedAttributes;
     66 
     67     private SignerInfo(int version,
     68             Object[] issuerAndSerialNumber,
     69             AlgorithmIdentifier digestAlgorithm,
     70             AuthenticatedAttributes authenticatedAttributes,
     71             AlgorithmIdentifier digestEncryptionAlgorithm,
     72             byte[] encryptedDigest,
     73             List<?> unauthenticatedAttributes) {
     74         this.version = version;
     75         this.issuer = ((Name)issuerAndSerialNumber[0]).getX500Principal();
     76         this.serialNumber = ASN1Integer.toBigIntegerValue(issuerAndSerialNumber[1]);
     77         this.digestAlgorithm = digestAlgorithm;
     78         this.authenticatedAttributes = authenticatedAttributes;
     79         this.digestEncryptionAlgorithm = digestEncryptionAlgorithm;
     80         this.encryptedDigest = encryptedDigest;
     81         this.unauthenticatedAttributes = unauthenticatedAttributes;
     82     }
     83 
     84     public X500Principal getIssuer() {
     85         return issuer;
     86     }
     87 
     88     public BigInteger getSerialNumber() {
     89         return serialNumber;
     90     }
     91 
     92     public String getDigestAlgorithm() {
     93         return digestAlgorithm.getAlgorithm();
     94     }
     95 
     96     public String getDigestAlgorithmName() {
     97         return digestAlgorithm.getAlgorithmName();
     98     }
     99 
    100     public String getDigestEncryptionAlgorithm() {
    101         return digestEncryptionAlgorithm.getAlgorithm();
    102     }
    103 
    104     public String getDigestEncryptionAlgorithmName() {
    105         return digestEncryptionAlgorithm.getAlgorithmName();
    106     }
    107 
    108     public List<AttributeTypeAndValue> getAuthenticatedAttributes() {
    109         if (authenticatedAttributes == null) {
    110             return null;
    111         }
    112         return authenticatedAttributes.getAttributes();
    113     }
    114 
    115     /**
    116      * Returns the non-IMPLICIT ASN.1 encoding of the "authAttrs" from this
    117      * SignerInfo. That is, it will return as the encoding of a generic ASN.1
    118      * SET.
    119      */
    120     public byte[] getEncodedAuthenticatedAttributes() {
    121         if (authenticatedAttributes == null) {
    122             return null;
    123         }
    124         return AuthenticatedAttributes.ASN1.encode(authenticatedAttributes.getAttributes());
    125     }
    126 
    127     public byte[] getEncryptedDigest() {
    128         return encryptedDigest;
    129     }
    130 
    131 
    132     public String toString() {
    133         StringBuilder res = new StringBuilder();
    134         res.append("-- SignerInfo:");
    135         res.append("\n version : ");
    136         res.append(version);
    137         res.append("\nissuerAndSerialNumber:  ");
    138         res.append(issuer);
    139         res.append("   ");
    140         res.append(serialNumber);
    141         res.append("\ndigestAlgorithm:  ");
    142         res.append(digestAlgorithm.toString());
    143         res.append("\nauthenticatedAttributes:  ");
    144         if (authenticatedAttributes != null) {
    145             res.append(authenticatedAttributes.toString());
    146         }
    147         res.append("\ndigestEncryptionAlgorithm: ");
    148         res.append(digestEncryptionAlgorithm.toString());
    149         res.append("\nunauthenticatedAttributes: ");
    150         if (unauthenticatedAttributes != null) {
    151             res.append(unauthenticatedAttributes.toString());
    152         }
    153         res.append("\n-- SignerInfo End\n");
    154         return res.toString();
    155     }
    156 
    157 
    158     public static final ASN1Sequence ISSUER_AND_SERIAL_NUMBER =
    159             new ASN1Sequence(new ASN1Type[] {
    160                 Name.ASN1,                       // issuer
    161                 ASN1Integer.getInstance(),       // serialNumber
    162             })
    163         {
    164             // method to encode
    165             @Override public void getValues(Object object, Object[] values) {
    166                 Object [] issAndSerial = (Object[])object;
    167                 values[0] = issAndSerial[0];
    168                 values[1] = issAndSerial[1];
    169         }
    170     };
    171 
    172     public static final ASN1Sequence ASN1 =
    173         new ASN1Sequence(new ASN1Type[] {
    174                 ASN1Integer.getInstance(),         //version
    175                 ISSUER_AND_SERIAL_NUMBER,
    176                 AlgorithmIdentifier.ASN1,           //digestAlgorithm
    177                 new ASN1Implicit(0, AuthenticatedAttributes.ASN1),//authenticatedAttributes
    178                 AlgorithmIdentifier.ASN1,            //digestEncryptionAlgorithm
    179                 ASN1OctetString.getInstance(),       //encryptedDigest
    180                  new ASN1Implicit(1, new ASN1SetOf(
    181                          AttributeTypeAndValue.ASN1)),//unauthenticatedAttributes
    182                 })  {
    183         {
    184             setOptional(3); // authenticatedAttributes is optional
    185             setOptional(6); // unauthenticatedAttributes is optional
    186         }
    187 
    188         @Override protected void getValues(Object object, Object[] values) {
    189             SignerInfo si = (SignerInfo) object;
    190             values[0] = new byte[] {(byte)si.version};
    191             try {
    192                 values[1] = new Object[] { new Name(si.issuer.getName()),
    193                         si.serialNumber.toByteArray() };
    194             } catch (IOException e) {
    195                 // The exception is never thrown, because si.issuer
    196                 // is created using Name.getX500Principal().
    197                 // Throw a RuntimeException just to be safe.
    198                 throw new RuntimeException("Failed to encode issuer name", e);
    199             }
    200             values[2] = si.digestAlgorithm;
    201             values[3] = si.authenticatedAttributes;
    202             values[4] = si.digestEncryptionAlgorithm;
    203             values[5] = si.encryptedDigest;
    204             values[6] = si.unauthenticatedAttributes;
    205         }
    206 
    207         @Override protected Object getDecodedObject(BerInputStream in) {
    208             Object[] values = (Object[]) in.content;
    209             return new SignerInfo(
    210                         ASN1Integer.toIntValue(values[0]),
    211                         (Object[]) values[1],
    212                         (AlgorithmIdentifier) values[2],
    213                         (AuthenticatedAttributes) values[3],
    214                         (AlgorithmIdentifier) values[4],
    215                         (byte[]) values[5],
    216                         (List) values[6]
    217                     );
    218         }
    219    };
    220 }
    221