View Javadoc
1   /*
2    * Copyright (c) 2003, 2004, Oracle and/or its affiliates. All rights reserved.
3    * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4    *
5    * This code is free software; you can redistribute it and/or modify it
6    * under the terms of the GNU General Public License version 2 only, as
7    * published by the Free Software Foundation.  Oracle designates this
8    * particular file as subject to the "Classpath" exception as provided
9    * by Oracle in the LICENSE file that accompanied this code.
10   *
11   * This code is distributed in the hope that it will be useful, but WITHOUT
12   * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13   * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
14   * version 2 for more details (a copy is included in the LICENSE file that
15   * accompanied this code).
16   *
17   * You should have received a copy of the GNU General Public License version
18   * 2 along with this work; if not, write to the Free Software Foundation,
19   * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20   *
21   * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
22   * or visit www.oracle.com if you need additional information or have any
23   * questions.
24   */
25  
26  package sun.security.pkcs;
27  
28  import java.io.IOException;
29  import java.util.ArrayList;
30  
31  import sun.misc.HexDumpEncoder;
32  import sun.security.util.DerInputStream;
33  import sun.security.util.DerValue;
34  import sun.security.x509.GeneralNames;
35  import sun.security.x509.SerialNumber;
36  
37  /**
38   * This class represents a signing certificate attribute.
39   * Its attribute value is defined by the following ASN.1 definition.
40   * <pre>
41   *
42   *   id-aa-signingCertificate OBJECT IDENTIFIER ::= { iso(1)
43   *     member-body(2) us(840) rsadsi(113549) pkcs(1) pkcs9(9)
44   *     smime(16) id-aa(2) 12 }
45   *
46   *   SigningCertificate ::=  SEQUENCE {
47   *       certs       SEQUENCE OF ESSCertID,
48   *       policies    SEQUENCE OF PolicyInformation OPTIONAL
49   *   }
50   *
51   *   ESSCertID ::=  SEQUENCE {
52   *       certHash        Hash,
53   *       issuerSerial    IssuerSerial OPTIONAL
54   *   }
55   *
56   *   Hash ::= OCTET STRING -- SHA1 hash of entire certificate
57   *
58   *   IssuerSerial ::= SEQUENCE {
59   *       issuer         GeneralNames,
60   *       serialNumber   CertificateSerialNumber
61   *   }
62   *
63   *   PolicyInformation ::= SEQUENCE {
64   *       policyIdentifier   CertPolicyId,
65   *       policyQualifiers   SEQUENCE SIZE (1..MAX) OF
66   *               PolicyQualifierInfo OPTIONAL }
67   *
68   *   CertPolicyId ::= OBJECT IDENTIFIER
69   *
70   *   PolicyQualifierInfo ::= SEQUENCE {
71   *       policyQualifierId  PolicyQualifierId,
72   *       qualifier        ANY DEFINED BY policyQualifierId }
73   *
74   *   -- Implementations that recognize additional policy qualifiers MUST
75   *   -- augment the following definition for PolicyQualifierId
76   *
77   *   PolicyQualifierId ::= OBJECT IDENTIFIER ( id-qt-cps | id-qt-unotice )
78   *
79   * </pre>
80   *
81   * @since 1.5
82   * @author Vincent Ryan
83   */
84  public class SigningCertificateInfo {
85  
86      private byte[] ber = null;
87  
88      private ESSCertId[] certId = null;
89  
90      public SigningCertificateInfo(byte[] ber) throws IOException {
91          parse(ber);
92      }
93  
94      public String toString() {
95          StringBuffer buffer = new StringBuffer();
96          buffer.append("[\n");
97          for (int i = 0; i < certId.length; i++) {
98              buffer.append(certId[i].toString());
99          }
100         // format policies as a string
101         buffer.append("\n]");
102 
103         return buffer.toString();
104     }
105 
106     public void parse(byte[] bytes) throws IOException {
107 
108         // Parse signingCertificate
109         DerValue derValue = new DerValue(bytes);
110         if (derValue.tag != DerValue.tag_Sequence) {
111             throw new IOException("Bad encoding for signingCertificate");
112         }
113 
114         // Parse certs
115         DerValue[] certs = derValue.data.getSequence(1);
116         certId = new ESSCertId[certs.length];
117         for (int i = 0; i < certs.length; i++) {
118             certId[i] = new ESSCertId(certs[i]);
119         }
120 
121         // Parse policies, if present
122         if (derValue.data.available() > 0) {
123             DerValue[] policies = derValue.data.getSequence(1);
124             for (int i = 0; i < policies.length; i++) {
125                 // parse PolicyInformation
126             }
127         }
128     }
129 }
130 
131 class ESSCertId {
132 
133     private static volatile HexDumpEncoder hexDumper;
134 
135     private byte[] certHash;
136     private GeneralNames issuer;
137     private SerialNumber serialNumber;
138 
139     ESSCertId(DerValue certId) throws IOException {
140         // Parse certHash
141         certHash = certId.data.getDerValue().toByteArray();
142 
143         // Parse issuerSerial, if present
144         if (certId.data.available() > 0) {
145             DerValue issuerSerial = certId.data.getDerValue();
146             // Parse issuer
147             issuer = new GeneralNames(issuerSerial.data.getDerValue());
148             // Parse serialNumber
149             serialNumber = new SerialNumber(issuerSerial.data.getDerValue());
150         }
151     }
152 
153     public String toString() {
154         StringBuffer buffer = new StringBuffer();
155         buffer.append("[\n\tCertificate hash (SHA-1):\n");
156         if (hexDumper == null) {
157             hexDumper = new HexDumpEncoder();
158         }
159         buffer.append(hexDumper.encode(certHash));
160         if (issuer != null && serialNumber != null) {
161             buffer.append("\n\tIssuer: " + issuer + "\n");
162             buffer.append("\t" + serialNumber);
163         }
164         buffer.append("\n]");
165         return buffer.toString();
166     }
167 }