OpenCores
URL https://opencores.org/ocsvn/scarts/scarts/trunk

Subversion Repositories scarts

[/] [scarts/] [trunk/] [toolchain/] [scarts-gcc/] [gcc-4.1.1/] [libjava/] [classpath/] [gnu/] [java/] [security/] [pkcs/] [PKCS7SignedData.java] - Blame information for rev 14

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 14 jlechner
/* PKCS7SignedData.java -- reader for PKCS#7 signedData objects
2
   Copyright (C) 2004, 2005  Free Software Foundation, Inc.
3
 
4
This file is part of GNU Classpath.
5
 
6
GNU Classpath is free software; you can redistribute it and/or modify
7
it under the terms of the GNU General Public License as published by
8
the Free Software Foundation; either version 2, or (at your option)
9
any later version.
10
 
11
GNU Classpath is distributed in the hope that it will be useful, but
12
WITHOUT ANY WARRANTY; without even the implied warranty of
13
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14
General Public License for more details.
15
 
16
You should have received a copy of the GNU General Public License
17
along with GNU Classpath; see the file COPYING.  If not, write to the
18
Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
19
02110-1301 USA.
20
 
21
Linking this library statically or dynamically with other modules is
22
making a combined work based on this library.  Thus, the terms and
23
conditions of the GNU General Public License cover the whole
24
combination.
25
 
26
As a special exception, the copyright holders of this library give you
27
permission to link this library with independent modules to produce an
28
executable, regardless of the license terms of these independent
29
modules, and to copy and distribute the resulting executable under
30
terms of your choice, provided that you also meet, for each linked
31
independent module, the terms and conditions of the license of that
32
module.  An independent module is a module which is not derived from
33
or based on this library.  If you modify this library, you may extend
34
this exception to your version of the library, but you are not
35
obligated to do so.  If you do not wish to do so, delete this
36
exception statement from your version. */
37
 
38
package gnu.java.security.pkcs;
39
 
40
import gnu.java.security.OID;
41
import gnu.java.security.ber.BER;
42
import gnu.java.security.ber.BEREncodingException;
43
import gnu.java.security.ber.BERReader;
44
import gnu.java.security.ber.BERValue;
45
import gnu.java.security.der.DERValue;
46
 
47
import java.io.ByteArrayInputStream;
48
import java.io.IOException;
49
import java.io.InputStream;
50
 
51
import java.math.BigInteger;
52
 
53
import java.security.cert.CRL;
54
import java.security.cert.CRLException;
55
import java.security.cert.Certificate;
56
import java.security.cert.CertificateException;
57
import java.security.cert.CertificateFactory;
58
 
59
import java.util.ArrayList;
60
import java.util.Collections;
61
import java.util.HashSet;
62
import java.util.Iterator;
63
import java.util.LinkedList;
64
import java.util.List;
65
import java.util.Set;
66
 
67
/**
68
 * The SignedData object in PKCS #7. This is a read-only implementation of
69
 * this format, and is used to provide signed Jar file support.
70
 *
71
 * @author Casey Marshall (csm@gnu.org)
72
 */
73
public class PKCS7SignedData
74
{
75
 
76
  public static final OID PKCS7_DATA = new OID("1.2.840.113549.1.7.1");
77
  public static final OID PKCS7_SIGNED_DATA = new OID("1.2.840.113549.1.7.2");
78
 
79
  private BigInteger version;
80
  private Set digestAlgorithms;
81
  private OID contentType;
82
  private byte[] content;
83
  private Certificate[] certificates;
84
  private CRL[] crls;
85
  private Set signerInfos;
86
 
87
  private static final boolean DEBUG = false;
88
  private static void debug(String msg)
89
  {
90
    System.err.print("PKCS7SignedData >> ");
91
    System.err.println(msg);
92
  }
93
 
94
  public PKCS7SignedData(InputStream in)
95
    throws CRLException, CertificateException, IOException
96
  {
97
    this(new BERReader(in));
98
  }
99
 
100
  /**
101
   * Parse an encoded PKCS#7 SignedData object. The ASN.1 format of this
102
   * object is:
103
   *
104
   * <pre>
105
   * SignedData ::= SEQUENCE {
106
   *   version Version,
107
   *   digestAlgorithms DigestAlgorithmIdentifiers,
108
   *   contentInfo ContentInfo,
109
   *   certificates
110
   *     [0] IMPLICIT ExtendedCertificatesAndCertificates OPTIONAL,
111
   *   crls
112
   *     [1] IMPLICIT CertificateRevocationLists OPTIONAL,
113
   *   signerInfos SignerInfos }
114
   *
115
   * Version ::= INTEGER
116
   *
117
   * DigestAlgorithmIdentifiers ::= SET OF DigestAlgorithmIdentifier
118
   *
119
   * DigestAlgorithmIdentifier ::= AlgorithmIdentifier
120
   *
121
   * ContentInfo ::= SEQUENCE {
122
   *   contentType ContentType,
123
   *   content [0] EXPLICIT ANY DEFINED BY contentType OPTIONAL }
124
   *
125
   * ContentType ::= OBJECT IDENTIFIER
126
   *
127
   * ExtendedCertificatesAndCertificates ::=
128
   *   SET OF ExtendedCertificatesAndCertificate
129
   *
130
   * ExtendedCertificatesAndCertificate ::= CHOICE {
131
   *   certificate Certificate, -- from X.509
132
   *   extendedCertificate [0] IMPLICIT ExtendedCertificate }
133
   *
134
   * CertificateRevocationLists ::= SET OF CertificateRevocationList
135
   *   -- from X.509
136
   *
137
   * SignerInfos ::= SET OF SignerInfo
138
   *
139
   * SignerInfo ::= SEQUENCE {
140
   *   version Version,
141
   *   issuerAndSerialNumber IssuerAndSerialNumber,
142
   *   digestAlgorithm DigestAlgorithmIdentifier,
143
   *   authenticatedAttributes
144
   *     [0] IMPLICIT Attributes OPTIONAL,
145
   *   digestEncryptionAlgorithm DigestEncryptionAlgorithmIdentifier,
146
   *   encryptedDigest EncryptedDigest,
147
   *   unauthenticatedAttributes
148
   *     [1] IMPLICIT Attributes OPTIONAL }
149
   *
150
   * EncryptedDigest ::= OCTET STRING
151
   * </pre>
152
   *
153
   * <p>(Readers who are confused as to why it takes 40 levels of indirection
154
   * to specify "data with a signature", rest assured that the present author
155
   * is as confused as you are).</p>
156
   */
157
  public PKCS7SignedData(BERReader ber)
158
    throws CRLException, CertificateException, IOException
159
  {
160
    CertificateFactory x509 = CertificateFactory.getInstance("X509");
161
    DERValue val = ber.read();
162
    if (!val.isConstructed())
163
      throw new BEREncodingException("malformed ContentInfo");
164
 
165
    val = ber.read();
166
    if (val.getTag() != BER.OBJECT_IDENTIFIER)
167
      throw new BEREncodingException("malformed ContentType");
168
 
169
    if (!PKCS7_SIGNED_DATA.equals(val.getValue()))
170
      throw new BEREncodingException("content is not SignedData");
171
 
172
    val = ber.read();
173
    if (val.getTag() != 0)
174
      throw new BEREncodingException("malformed Content");
175
 
176
    val = ber.read();
177
    if (!val.isConstructed())
178
      throw new BEREncodingException("malformed SignedData");
179
 
180
    if (DEBUG)
181
      debug("SignedData: " + val);
182
 
183
    val = ber.read();
184
    if (val.getTag() != BER.INTEGER)
185
      throw new BEREncodingException("expecting Version");
186
    version = (BigInteger) val.getValue();
187
 
188
    if (DEBUG)
189
      debug("  Version: " + version);
190
 
191
    digestAlgorithms = new HashSet();
192
    val = ber.read();
193
    if (!val.isConstructed())
194
      throw new BEREncodingException("malformed DigestAlgorithmIdentifiers");
195
    if (DEBUG)
196
      debug("  DigestAlgorithmIdentifiers: " + val);
197
    int count = 0;
198
    DERValue val2 = ber.read();
199
    while (val2 != BER.END_OF_SEQUENCE &&
200
           (val.getLength() > 0 && val.getLength() > count))
201
      {
202
        if (!val2.isConstructed())
203
          throw new BEREncodingException("malformed AlgorithmIdentifier");
204
        if (DEBUG)
205
          debug("    AlgorithmIdentifier: " + val2);
206
        count += val2.getEncodedLength();
207
        val2 = ber.read();
208
        if (val2.getTag() != BER.OBJECT_IDENTIFIER)
209
          throw new BEREncodingException("malformed AlgorithmIdentifier");
210
        if (DEBUG)
211
          debug("      ID: " + val2.getValue());
212
        List algId = new ArrayList(2);
213
        algId.add(val2.getValue());
214
        val2 = ber.read();
215
        if (val2 != BER.END_OF_SEQUENCE)
216
          {
217
            count += val2.getEncodedLength();
218
            if (val2.getTag() == BER.NULL)
219
              algId.add(null);
220
            else
221
              algId.add(val2.getEncoded());
222
            if (DEBUG)
223
              debug("      params: " + new BigInteger(1, val2.getEncoded()).toString(16));
224
            if (val2.isConstructed())
225
              ber.skip(val2.getLength());
226
            if (BERValue.isIndefinite(val))
227
              val2 = ber.read();
228
          }
229
        else
230
          algId.add(null);
231
        digestAlgorithms.add(algId);
232
      }
233
 
234
    val = ber.read();
235
    if (!val.isConstructed())
236
      throw new BEREncodingException("malformed ContentInfo");
237
    if (DEBUG)
238
      debug("  ContentInfo: " + val);
239
    val2 = ber.read();
240
    if (val2.getTag() != BER.OBJECT_IDENTIFIER)
241
      throw new BEREncodingException("malformed ContentType");
242
    contentType = (OID) val2.getValue();
243
    if (DEBUG)
244
      debug("    ContentType: " + contentType);
245
    if (BERValue.isIndefinite(val)
246
        || (val.getLength() > 0 && val.getLength() > val2.getEncodedLength()))
247
      {
248
        val2 = ber.read();
249
        if (val2 != BER.END_OF_SEQUENCE)
250
          {
251
            content = val2.getEncoded();
252
            if (BERValue.isIndefinite(val))
253
              val2 = ber.read();
254
            if (DEBUG)
255
              debug("    Content: " + new BigInteger(1, content).toString(16));
256
          }
257
      }
258
 
259
    val = ber.read();
260
    if (val.getTag() == 0)
261
      {
262
        if (!val.isConstructed())
263
          throw new BEREncodingException("malformed ExtendedCertificatesAndCertificates");
264
        if (DEBUG)
265
          debug("  ExtendedCertificatesAndCertificates: " + val);
266
        count = 0;
267
        val2 = ber.read();
268
        List certs = new LinkedList();
269
        while (val2 != BER.END_OF_SEQUENCE &&
270
               (val.getLength() > 0 && val.getLength() > count))
271
          {
272
            Certificate cert =
273
              x509.generateCertificate(new ByteArrayInputStream(val2.getEncoded()));
274
            if (DEBUG)
275
              debug("    Certificate: " + cert);
276
            certs.add(cert);
277
            count += val2.getEncodedLength();
278
            ber.skip(val2.getLength());
279
            if (BERValue.isIndefinite(val) || val.getLength() > count)
280
              val2 = ber.read();
281
          }
282
        certificates = (Certificate[]) certs.toArray(new Certificate[certs.size()]);
283
        val = ber.read();
284
      }
285
 
286
    if (val.getTag() == 1)
287
      {
288
        if (!val.isConstructed())
289
          throw new BEREncodingException("malformed CertificateRevocationLists");
290
        if (DEBUG)
291
          debug("  CertificateRevocationLists: " + val);
292
        count = 0;
293
        val2 = ber.read();
294
        List crls = new LinkedList();
295
        while (val2 != BER.END_OF_SEQUENCE &&
296
               (val.getLength() > 0 && val.getLength() > count))
297
          {
298
            CRL crl = x509.generateCRL(new ByteArrayInputStream(val2.getEncoded()));
299
            if (DEBUG)
300
              debug ("    CRL: " + crl);
301
            crls.add(crl);
302
            count += val2.getEncodedLength();
303
            ber.skip(val2.getLength());
304
            if (BERValue.isIndefinite(val) || val.getLength() > count)
305
              val2 = ber.read();
306
          }
307
        this.crls = (CRL[]) crls.toArray(new CRL[crls.size()]);
308
        val = ber.read();
309
      }
310
 
311
    signerInfos = new HashSet();
312
    if (!val.isConstructed())
313
      throw new BEREncodingException("malformed SignerInfos");
314
 
315
    if (DEBUG)
316
      debug("  SignerInfos: " + val);
317
 
318
    // FIXME read this more carefully.
319
    // Since we are just reading a file (probably) we just read until we
320
    // reach the end.
321
    while (true)
322
      {
323
        int i = ber.peek();
324
        if (i == 0 || i == -1)
325
          break;
326
        signerInfos.add(new SignerInfo(ber));
327
      }
328
  }
329
 
330
  public BigInteger getVersion()
331
  {
332
    return version;
333
  }
334
 
335
  public Certificate[] getCertificates()
336
  {
337
    return (certificates != null ? (Certificate[]) certificates.clone()
338
            : null);
339
  }
340
 
341
  public OID getContentType()
342
  {
343
    return contentType;
344
  }
345
 
346
  public byte[] getContent()
347
  {
348
    return (content != null ? (byte[]) content.clone() : null);
349
  }
350
 
351
  public Set getDigestAlgorithms()
352
  {
353
    // FIXME copy contents too, they are mutable!!!
354
    return Collections.unmodifiableSet(digestAlgorithms);
355
  }
356
 
357
  public Set getSignerInfos()
358
  {
359
    Set copy = new HashSet();
360
    for (Iterator it = signerInfos.iterator(); it.hasNext(); )
361
      copy.add(it.next());
362
    return Collections.unmodifiableSet(copy);
363
  }
364
}

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.