Imported GNU Classpath 0.90
[official-gcc.git] / libjava / classpath / gnu / java / security / pkcs / SignerInfo.java
blob7b38bfefdafac0c8dd58a63b0a5c1f86353f7d86
1 /* SignerInfo.java -- a SignerInfo object, from PKCS #7
2 Copyright (C) 2004, 2005 Free Software Foundation, Inc.
4 This file is part of GNU Classpath.
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.
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.
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.
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.
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. */
38 package gnu.java.security.pkcs;
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.DER;
46 import gnu.java.security.der.DERValue;
47 import gnu.java.security.der.DERWriter;
48 import gnu.java.security.util.Util;
50 import java.io.ByteArrayOutputStream;
51 import java.io.IOException;
52 import java.io.OutputStream;
54 import java.math.BigInteger;
55 import java.util.ArrayList;
56 import java.util.logging.Logger;
58 import javax.security.auth.x500.X500Principal;
60 public class SignerInfo
62 private static final Logger log = Logger.getLogger(SignerInfo.class.getName());
64 private final BigInteger version;
65 private final BigInteger serialNumber;
66 private final X500Principal issuer;
67 private final OID digestAlgorithmId;
68 private final byte[] digestAlgorithmParams;
69 private final byte[] authenticatedAttributes;
70 private final OID digestEncryptionAlgorithmId;
71 private final byte[] digestEncryptionAlgorithmParams;
72 private final byte[] encryptedDigest;
73 private final byte[] unauthenticatedAttributes;
75 /**
76 * Parse a SignerInfo object.
77 * <p>
78 * A SignerInfo is a structure with the following ASN.1 syntax:
79 * <pre>
80 * SignerInfo ::= SEQUENCE {
81 * version Version, -- always 1 for PKCS7 v1.5
82 * issuerAndSerialNumber IssuerAndSerialNumber, -- an INTEGER
83 * digestAlgorithm DigestAlgorithmIdentifier,
84 * authenticatedAttributes [0] IMPLICIT Attributes OPTIONAL,
85 * digestEncryptionAlgorithm DigestEncryptionAlgorithmIdentifier,
86 * encryptedDigest EncryptedDigest,
87 * unauthenticatedAttributes [1] IMPLICIT Attributes OPTIONAL }
89 * IssuerAndSerialNumber ::= SEQUENCE {
90 * issuer Name,
91 * serialNumber CertificateSerialNumber
92 * }
94 * DigestAlgorithmIdentifier ::= AlgorithmIdentifier
96 * DigestEncryptionAlgorithmIdentifier ::= AlgorithmIdentifier
98 * EncryptedDigest ::= OCTET STRING
99 * </pre>
101 public SignerInfo(BERReader ber) throws IOException
103 DERValue val = ber.read();
104 log.finest("SignerInfo: " + val);
105 if (!val.isConstructed())
106 throw new BEREncodingException("malformed SignerInfo");
108 val = ber.read();
109 if (val.getTag() != BER.INTEGER)
110 throw new BEREncodingException("malformed Version");
112 version = (BigInteger) val.getValue();
113 log.finest(" Version: " + version);
115 val = ber.read();
116 if (!val.isConstructed())
117 throw new BEREncodingException("malformed IssuerAndSerialNumber");
119 log.finest(" IssuerAndSerialNumber: " + val);
121 val = ber.read();
122 if (!val.isConstructed())
123 throw new BEREncodingException("malformed Issuer");
125 issuer = new X500Principal(val.getEncoded());
126 ber.skip(val.getLength());
127 log.finest(" Issuer: " + issuer);
129 val = ber.read();
130 if (val.getTag() != BER.INTEGER)
131 throw new BEREncodingException("malformed SerialNumber");
133 serialNumber = (BigInteger) val.getValue();
134 log.finest(" SerialNumber: " + serialNumber);
136 val = ber.read();
137 if (!val.isConstructed())
138 throw new BEREncodingException("malformed DigestAlgorithmIdentifier");
140 log.finest(" DigestAlgorithmIdentifier: " + val);
142 int count = 0;
143 DERValue val2 = ber.read();
144 if (val2.getTag() != BER.OBJECT_IDENTIFIER)
145 throw new BEREncodingException("malformed AlgorithmIdentifier");
147 digestAlgorithmId = (OID) val2.getValue();
148 log.finest(" digestAlgorithm OID: " + digestAlgorithmId);
150 if (BERValue.isIndefinite(val))
152 val2 = ber.read();
153 if (val2 != BER.END_OF_SEQUENCE)
155 digestAlgorithmParams = val2.getEncoded();
156 val2 = ber.read();
157 if (val2 != BER.END_OF_SEQUENCE)
158 throw new BEREncodingException("expecting BER end-of-sequence");
160 else
161 digestAlgorithmParams = null;
163 else if (val2.getEncodedLength() < val.getLength())
165 val2 = ber.read();
166 digestAlgorithmParams = val2.getEncoded();
167 if (val2.isConstructed())
168 ber.skip(val2.getLength());
170 else
171 digestAlgorithmParams = null;
173 log.finest(" digestAlgorithm params: ");
174 log.finest(Util.dumpString(digestAlgorithmParams,
175 " digestAlgorithm params: "));
177 val = ber.read();
178 if (val.getTag() == 0)
180 authenticatedAttributes = val.getEncoded();
181 val = ber.read();
182 if (val.isConstructed())
183 ber.skip(val.getLength());
185 val = ber.read();
187 else
188 authenticatedAttributes = null;
190 log.finest(" AuthenticatedAttributes: ");
191 log.finest(Util.dumpString(authenticatedAttributes,
192 " AuthenticatedAttributes: "));
194 if (!val.isConstructed())
195 throw new BEREncodingException("malformed DigestEncryptionAlgorithmIdentifier");
197 log.finest(" DigestEncryptionAlgorithmIdentifier: " + val);
198 count = 0;
199 val2 = ber.read();
200 if (val2.getTag() != BER.OBJECT_IDENTIFIER)
201 throw new BEREncodingException("malformed AlgorithmIdentifier");
203 digestEncryptionAlgorithmId = (OID) val2.getValue();
204 log.finest(" digestEncryptionAlgorithm OID: " + digestEncryptionAlgorithmId);
206 if (BERValue.isIndefinite(val))
208 val2 = ber.read();
209 if (val2 != BER.END_OF_SEQUENCE)
211 digestEncryptionAlgorithmParams = val2.getEncoded();
212 val2 = ber.read();
213 if (val2 != BER.END_OF_SEQUENCE)
214 throw new BEREncodingException("expecting BER end-of-sequence");
216 else
217 digestEncryptionAlgorithmParams = null;
219 else if (val2.getEncodedLength() < val.getLength())
221 val2 = ber.read();
222 digestEncryptionAlgorithmParams = val2.getEncoded();
223 if (val2.isConstructed())
224 ber.skip(val2.getLength());
226 else
227 digestEncryptionAlgorithmParams = null;
229 log.finest(" digestEncryptionAlgorithm params: ");
230 log.finest(Util.dumpString(digestEncryptionAlgorithmParams,
231 " digestEncryptionAlgorithm params: "));
233 val = ber.read();
234 if (val.getTag() != BER.OCTET_STRING)
235 throw new BEREncodingException("malformed EncryptedDigest");
237 encryptedDigest = (byte[]) val.getValue();
238 log.finest(" EncryptedDigest: ");
239 log.finest(Util.dumpString(encryptedDigest, " EncryptedDigest: "));
241 if (ber.peek() == 1)
242 unauthenticatedAttributes = ber.read().getEncoded();
243 else
244 unauthenticatedAttributes = null;
246 log.finest(" UnauthenticatedAttributes: ");
247 log.finest(Util.dumpString(unauthenticatedAttributes,
248 " UnauthenticatedAttributes: "));
250 if (ber.peek() == 0)
251 ber.read();
255 * Constructs a new instance of <code>SignerInfo</code> given a designated
256 * set of fields.
258 * @param issuer the X.500 Principal name of the signer referenced by this
259 * instance.
260 * @param serialNumber the serial number of the certificate being used. Both
261 * this and the previous arguments are gleaned from the signer's
262 * certificate.
263 * @param digestAlgorithmOID the OID of the digest algorithm. When
264 * constructing the DigestAlgorithmIdentifier with this OID, the
265 * parameters part will be NULL.
266 * @param authenticatedAttributes the encoding of the set of authenticated
267 * attributes to use.
268 * @param digestEncryptionAlgorithmOID the OID of the digest encryption
269 * algorithm. When constructing the
270 * DigestEncryptionAlgorithmIdentifier with this OID, the parameters
271 * part will be NULL.
272 * @param encryptedDigest the encrypted hash generated with this signer's
273 * private key.
274 * @param unauthenticatedAttributes the encoding of the set of
275 * unauthencticated attributes.
277 public SignerInfo(X500Principal issuer, BigInteger serialNumber,
278 OID digestAlgorithmOID, byte[] authenticatedAttributes,
279 OID digestEncryptionAlgorithmOID,
280 byte[] encryptedDigest, byte[] unauthenticatedAttributes)
282 super();
284 this.version = BigInteger.ONE;
285 this.issuer = issuer;
286 this.serialNumber = serialNumber;
287 this.digestAlgorithmId = digestAlgorithmOID;
288 this.digestAlgorithmParams = null;
289 this.authenticatedAttributes = authenticatedAttributes;
290 this.digestEncryptionAlgorithmId = digestEncryptionAlgorithmOID;
291 this.digestEncryptionAlgorithmParams = null;
292 this.encryptedDigest = encryptedDigest;
293 this.unauthenticatedAttributes = unauthenticatedAttributes;
296 public BigInteger getVersion()
298 return version;
301 public BigInteger getSerialNumber()
303 return serialNumber;
306 public X500Principal getIssuer()
308 return issuer;
311 public OID getDigestAlgorithmId()
313 return digestAlgorithmId;
316 public byte[] getDigestAlgorithmParams()
318 return (digestAlgorithmParams != null
319 ? (byte[]) digestAlgorithmParams.clone()
320 : null);
323 public byte[] getAuthenticatedAttributes()
325 return (authenticatedAttributes != null
326 ? (byte[]) authenticatedAttributes.clone()
327 : null);
330 public OID getDigestEncryptionAlgorithmId()
332 return digestEncryptionAlgorithmId;
335 public byte[] getDigestEncryptionAlgorithmParams()
337 return (digestEncryptionAlgorithmParams != null
338 ? (byte[]) digestEncryptionAlgorithmParams.clone()
339 : null);
342 public byte[] getEncryptedDigest()
344 return (encryptedDigest != null ? (byte[]) encryptedDigest.clone() : null);
347 public byte[] getUnauthenticatedAttributes()
349 return (unauthenticatedAttributes != null
350 ? (byte[]) unauthenticatedAttributes.clone()
351 : null);
355 * Writes to the designated output stream the DER encoding of the current
356 * contents of this instance.
358 * @param out the destination output stream.
359 * @throws IOException if an I/O related exception occurs during the process.
361 public void encode(OutputStream out) throws IOException
363 DERValue derVersion = new DERValue(DER.INTEGER, version);
365 ByteArrayOutputStream baos = new ByteArrayOutputStream(4096);
366 baos.write(issuer.getEncoded());
367 DERValue derSerialNumber = new DERValue(DER.INTEGER, serialNumber);
368 DERWriter.write(baos, derSerialNumber);
369 baos.flush();
370 byte[] b = baos.toByteArray();
371 DERValue derIssuerAndSerialNumber =
372 new DERValue(DER.CONSTRUCTED | DER.SEQUENCE, b.length, b, null);
374 DERValue derDigestAlgorithmOID = new DERValue(DER.OBJECT_IDENTIFIER,
375 digestAlgorithmId);
376 ArrayList digestAlgorithmIdentifier = new ArrayList(1);
377 digestAlgorithmIdentifier.add(derDigestAlgorithmOID);
378 DERValue derDigestAlgorithmIdentifier =
379 new DERValue(DER.CONSTRUCTED | DER.SEQUENCE, digestAlgorithmIdentifier);
381 DERValue derAuthenticatedAttributes;
382 if (authenticatedAttributes == null)
383 derAuthenticatedAttributes = new DERValue(DER.NULL, null);
384 else
385 derAuthenticatedAttributes = new DERValue(DER.CONSTRUCTED | DER.SET,
386 authenticatedAttributes);
388 DERValue derDigestEncryptionAlgorithmOID =
389 new DERValue(DER.OBJECT_IDENTIFIER, digestEncryptionAlgorithmId);
390 ArrayList digestEncryptionAlgorithmIdentifier = new ArrayList(1);
391 digestEncryptionAlgorithmIdentifier.add(derDigestEncryptionAlgorithmOID);
392 DERValue derDigestEncryptionAlgorithmIdentifier =
393 new DERValue(DER.CONSTRUCTED | DER.SEQUENCE, digestEncryptionAlgorithmIdentifier);
395 DERValue derEncryptedDigest = new DERValue(DER.OCTET_STRING, encryptedDigest);
397 DERValue derUnauthenticatedAttributes;
398 if (unauthenticatedAttributes == null)
399 derUnauthenticatedAttributes = new DERValue(DER.NULL, null);
400 else
401 derUnauthenticatedAttributes = new DERValue(DER.CONSTRUCTED | DER.SET,
402 unauthenticatedAttributes);
404 ArrayList signerInfo = new ArrayList(5);
405 signerInfo.add(derVersion);
406 signerInfo.add(derIssuerAndSerialNumber);
407 signerInfo.add(derDigestAlgorithmIdentifier);
408 signerInfo.add(derDigestEncryptionAlgorithmIdentifier);
409 signerInfo.add(derEncryptedDigest);
410 DERValue derSignerInfo = new DERValue(DER.CONSTRUCTED | DER.SEQUENCE,
411 signerInfo);
412 DERWriter.write(out, derSignerInfo);