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