Source Code Cross Referenced for SignerInformation.java in  » Security » Bouncy-Castle » org » bouncycastle » cms » Java Source Code / Java DocumentationJava Source Code and Java Documentation

Java Source Code / Java Documentation
1. 6.0 JDK Core
2. 6.0 JDK Modules
3. 6.0 JDK Modules com.sun
4. 6.0 JDK Modules com.sun.java
5. 6.0 JDK Modules sun
6. 6.0 JDK Platform
7. Ajax
8. Apache Harmony Java SE
9. Aspect oriented
10. Authentication Authorization
11. Blogger System
12. Build
13. Byte Code
14. Cache
15. Chart
16. Chat
17. Code Analyzer
18. Collaboration
19. Content Management System
20. Database Client
21. Database DBMS
22. Database JDBC Connection Pool
23. Database ORM
24. Development
25. EJB Server geronimo
26. EJB Server GlassFish
27. EJB Server JBoss 4.2.1
28. EJB Server resin 3.1.5
29. ERP CRM Financial
30. ESB
31. Forum
32. GIS
33. Graphic Library
34. Groupware
35. HTML Parser
36. IDE
37. IDE Eclipse
38. IDE Netbeans
39. Installer
40. Internationalization Localization
41. Inversion of Control
42. Issue Tracking
43. J2EE
44. JBoss
45. JMS
46. JMX
47. Library
48. Mail Clients
49. Net
50. Parser
51. PDF
52. Portal
53. Profiler
54. Project Management
55. Report
56. RSS RDF
57. Rule Engine
58. Science
59. Scripting
60. Search Engine
61. Security
62. Sevlet Container
63. Source Control
64. Swing Library
65. Template Engine
66. Test Coverage
67. Testing
68. UML
69. Web Crawler
70. Web Framework
71. Web Mail
72. Web Server
73. Web Services
74. Web Services apache cxf 2.0.1
75. Web Services AXIS2
76. Wiki Engine
77. Workflow Engines
78. XML
79. XML UI
Java
Java Tutorial
Java Open Source
Jar File Download
Java Articles
Java Products
Java by API
Photoshop Tutorials
Maya Tutorials
Flash Tutorials
3ds-Max Tutorials
Illustrator Tutorials
GIMP Tutorials
C# / C Sharp
C# / CSharp Tutorial
C# / CSharp Open Source
ASP.Net
ASP.NET Tutorial
JavaScript DHTML
JavaScript Tutorial
JavaScript Reference
HTML / CSS
HTML CSS Reference
C / ANSI-C
C Tutorial
C++
C++ Tutorial
Ruby
PHP
Python
Python Tutorial
Python Open Source
SQL Server / T-SQL
SQL Server / T-SQL Tutorial
Oracle PL / SQL
Oracle PL/SQL Tutorial
PostgreSQL
SQL / MySQL
MySQL Tutorial
VB.Net
VB.Net Tutorial
Flash / Flex / ActionScript
VBA / Excel / Access / Word
XML
XML Tutorial
Microsoft Office PowerPoint 2007 Tutorial
Microsoft Office Excel 2007 Tutorial
Microsoft Office Word 2007 Tutorial
Java Source Code / Java Documentation » Security » Bouncy Castle » org.bouncycastle.cms 
Source Cross Referenced  Class Diagram Java Document (Java Doc) 


001:        package org.bouncycastle.cms;
002:
003:        import org.bouncycastle.asn1.ASN1InputStream;
004:        import org.bouncycastle.asn1.ASN1Null;
005:        import org.bouncycastle.asn1.ASN1OctetString;
006:        import org.bouncycastle.asn1.ASN1OutputStream;
007:        import org.bouncycastle.asn1.ASN1Sequence;
008:        import org.bouncycastle.asn1.ASN1Set;
009:        import org.bouncycastle.asn1.DEREncodable;
010:        import org.bouncycastle.asn1.DERNull;
011:        import org.bouncycastle.asn1.DERObject;
012:        import org.bouncycastle.asn1.DERObjectIdentifier;
013:        import org.bouncycastle.asn1.DEROutputStream;
014:        import org.bouncycastle.asn1.DERSet;
015:        import org.bouncycastle.asn1.DERTags;
016:        import org.bouncycastle.asn1.cms.Attribute;
017:        import org.bouncycastle.asn1.cms.AttributeTable;
018:        import org.bouncycastle.asn1.cms.CMSAttributes;
019:        import org.bouncycastle.asn1.cms.IssuerAndSerialNumber;
020:        import org.bouncycastle.asn1.cms.SignerIdentifier;
021:        import org.bouncycastle.asn1.cms.SignerInfo;
022:        import org.bouncycastle.asn1.cms.Time;
023:        import org.bouncycastle.asn1.x509.AlgorithmIdentifier;
024:        import org.bouncycastle.asn1.x509.DigestInfo;
025:
026:        import javax.crypto.Cipher;
027:        import java.io.ByteArrayOutputStream;
028:        import java.io.IOException;
029:        import java.security.GeneralSecurityException;
030:        import java.security.InvalidKeyException;
031:        import java.security.MessageDigest;
032:        import java.security.NoSuchAlgorithmException;
033:        import java.security.NoSuchProviderException;
034:        import java.security.PublicKey;
035:        import java.security.Signature;
036:        import java.security.SignatureException;
037:        import java.security.cert.CertificateExpiredException;
038:        import java.security.cert.CertificateNotYetValidException;
039:        import java.security.cert.X509Certificate;
040:
041:        /**
042:         * an expanded SignerInfo block from a CMS Signed message
043:         */
044:        public class SignerInformation {
045:            private SignerId sid;
046:            private SignerInfo info;
047:            private AlgorithmIdentifier digestAlgorithm;
048:            private AlgorithmIdentifier encryptionAlgorithm;
049:            private ASN1Set signedAttributes;
050:            private ASN1Set unsignedAttributes;
051:            private CMSProcessable content;
052:            private byte[] signature;
053:            private DERObjectIdentifier contentType;
054:            private byte[] _digest;
055:            private byte[] _resultDigest;
056:
057:            SignerInformation(SignerInfo info, DERObjectIdentifier contentType,
058:                    CMSProcessable content, byte[] digest) {
059:                this .info = info;
060:                this .sid = new SignerId();
061:                this .contentType = contentType;
062:
063:                try {
064:                    SignerIdentifier s = info.getSID();
065:
066:                    if (s.isTagged()) {
067:                        ASN1OctetString octs = ASN1OctetString.getInstance(s
068:                                .getId());
069:
070:                        sid.setSubjectKeyIdentifier(octs.getOctets());
071:                    } else {
072:                        IssuerAndSerialNumber iAnds = IssuerAndSerialNumber
073:                                .getInstance(s.getId());
074:
075:                        ByteArrayOutputStream bOut = new ByteArrayOutputStream();
076:                        ASN1OutputStream aOut = new ASN1OutputStream(bOut);
077:
078:                        aOut.writeObject(iAnds.getName());
079:
080:                        sid.setIssuer(bOut.toByteArray());
081:                        sid.setSerialNumber(iAnds.getSerialNumber().getValue());
082:                    }
083:                } catch (IOException e) {
084:                    throw new IllegalArgumentException(
085:                            "invalid sid in SignerInfo");
086:                }
087:
088:                this .digestAlgorithm = info.getDigestAlgorithm();
089:                this .signedAttributes = info.getAuthenticatedAttributes();
090:                this .unsignedAttributes = info.getUnauthenticatedAttributes();
091:                this .encryptionAlgorithm = info.getDigestEncryptionAlgorithm();
092:                this .signature = info.getEncryptedDigest().getOctets();
093:
094:                this .content = content;
095:                _digest = digest;
096:            }
097:
098:            private byte[] encodeObj(DEREncodable obj) throws IOException {
099:                if (obj != null) {
100:                    ByteArrayOutputStream bOut = new ByteArrayOutputStream();
101:                    ASN1OutputStream aOut = new ASN1OutputStream(bOut);
102:
103:                    aOut.writeObject(obj);
104:
105:                    return bOut.toByteArray();
106:                }
107:
108:                return null;
109:            }
110:
111:            public SignerId getSID() {
112:                return sid;
113:            }
114:
115:            /**
116:             * return the version number for this objects underlying SignerInfo structure.
117:             */
118:            public int getVersion() {
119:                return info.getVersion().getValue().intValue();
120:            }
121:
122:            /**
123:             * return the object identifier for the signature.
124:             */
125:            public String getDigestAlgOID() {
126:                return digestAlgorithm.getObjectId().getId();
127:            }
128:
129:            /**
130:             * return the signature parameters, or null if there aren't any.
131:             */
132:            public byte[] getDigestAlgParams() {
133:                try {
134:                    return encodeObj(digestAlgorithm.getParameters());
135:                } catch (Exception e) {
136:                    throw new RuntimeException(
137:                            "exception getting digest parameters " + e);
138:                }
139:            }
140:
141:            /**
142:             * return the content digest that was calculated during verification.
143:             */
144:            public byte[] getContentDigest() {
145:                if (_resultDigest == null) {
146:                    throw new IllegalStateException(
147:                            "method can only be called after verify.");
148:                }
149:
150:                return (byte[]) _resultDigest.clone();
151:            }
152:
153:            /**
154:             * return the object identifier for the signature.
155:             */
156:            public String getEncryptionAlgOID() {
157:                return encryptionAlgorithm.getObjectId().getId();
158:            }
159:
160:            /**
161:             * return the signature/encyrption algorithm parameters, or null if
162:             * there aren't any.
163:             */
164:            public byte[] getEncryptionAlgParams() {
165:                try {
166:                    return encodeObj(encryptionAlgorithm.getParameters());
167:                } catch (Exception e) {
168:                    throw new RuntimeException(
169:                            "exception getting encryption parameters " + e);
170:                }
171:            }
172:
173:            /**
174:             * return a table of the signed attributes - indexed by
175:             * the OID of the attribute.
176:             */
177:            public AttributeTable getSignedAttributes() {
178:                if (signedAttributes == null) {
179:                    return null;
180:                }
181:
182:                return new AttributeTable(signedAttributes);
183:            }
184:
185:            /**
186:             * return a table of the unsigned attributes indexed by
187:             * the OID of the attribute.
188:             */
189:            public AttributeTable getUnsignedAttributes() {
190:                if (unsignedAttributes == null) {
191:                    return null;
192:                }
193:
194:                return new AttributeTable(unsignedAttributes);
195:            }
196:
197:            /**
198:             * return the encoded signature
199:             */
200:            public byte[] getSignature() {
201:                return (byte[]) signature.clone();
202:            }
203:
204:            /**
205:             * return the DER encoding of the signed attributes.
206:             * @throws IOException if an encoding error occurs.
207:             */
208:            public byte[] getEncodedSignedAttributes() throws IOException {
209:                if (signedAttributes != null) {
210:                    ByteArrayOutputStream bOut = new ByteArrayOutputStream();
211:                    DEROutputStream aOut = new DEROutputStream(bOut);
212:
213:                    aOut.writeObject(signedAttributes);
214:
215:                    return bOut.toByteArray();
216:                }
217:
218:                return null;
219:            }
220:
221:            private boolean doVerify(PublicKey key,
222:                    AttributeTable signedAttrTable, String sigProvider)
223:                    throws CMSException, NoSuchAlgorithmException,
224:                    NoSuchProviderException {
225:                String digestName = CMSSignedHelper.INSTANCE
226:                        .getDigestAlgName(this .getDigestAlgOID());
227:                String signatureName = digestName
228:                        + "with"
229:                        + CMSSignedHelper.INSTANCE.getEncryptionAlgName(this 
230:                                .getEncryptionAlgOID());
231:                Signature sig = CMSSignedHelper.INSTANCE.getSignatureInstance(
232:                        signatureName, sigProvider);
233:                MessageDigest digest = CMSSignedHelper.INSTANCE
234:                        .getDigestInstance(digestName, sigProvider);
235:
236:                try {
237:                    sig.initVerify(key);
238:
239:                    if (signedAttributes == null) {
240:                        if (content != null) {
241:                            content
242:                                    .write(new CMSSignedDataGenerator.SigOutputStream(
243:                                            sig));
244:                            content
245:                                    .write(new CMSSignedDataGenerator.DigOutputStream(
246:                                            digest));
247:
248:                            _resultDigest = digest.digest();
249:                        } else {
250:                            _resultDigest = _digest;
251:
252:                            // need to decrypt signature and check message bytes
253:                            return verifyDigest(_digest, key, this 
254:                                    .getSignature(), sigProvider);
255:                        }
256:                    } else {
257:                        byte[] hash;
258:
259:                        if (content != null) {
260:                            content
261:                                    .write(new CMSSignedDataGenerator.DigOutputStream(
262:                                            digest));
263:
264:                            hash = digest.digest();
265:                        } else {
266:                            hash = _digest;
267:                        }
268:
269:                        _resultDigest = hash;
270:
271:                        Attribute dig = signedAttrTable
272:                                .get(CMSAttributes.messageDigest);
273:                        Attribute type = signedAttrTable
274:                                .get(CMSAttributes.contentType);
275:
276:                        if (dig == null) {
277:                            throw new SignatureException(
278:                                    "no hash for content found in signed attributes");
279:                        }
280:
281:                        if (type == null) {
282:                            throw new SignatureException(
283:                                    "no content type id found in signed attributes");
284:                        }
285:
286:                        DERObject hashObj = dig.getAttrValues().getObjectAt(0)
287:                                .getDERObject();
288:
289:                        if (hashObj instanceof  ASN1OctetString) {
290:                            byte[] signedHash = ((ASN1OctetString) hashObj)
291:                                    .getOctets();
292:
293:                            if (!MessageDigest.isEqual(hash, signedHash)) {
294:                                throw new SignatureException(
295:                                        "content hash found in signed attributes different");
296:                            }
297:                        } else if (hashObj instanceof  DERNull) {
298:                            if (hash != null) {
299:                                throw new SignatureException(
300:                                        "NULL hash found in signed attributes when one expected");
301:                            }
302:                        }
303:
304:                        DERObjectIdentifier typeOID = (DERObjectIdentifier) type
305:                                .getAttrValues().getObjectAt(0);
306:
307:                        if (!typeOID.equals(contentType)) {
308:                            throw new SignatureException(
309:                                    "contentType in signed attributes different");
310:                        }
311:
312:                        sig.update(this .getEncodedSignedAttributes());
313:                    }
314:
315:                    return sig.verify(this .getSignature());
316:                } catch (InvalidKeyException e) {
317:                    throw new CMSException(
318:                            "key not appropriate to signature in message.", e);
319:                } catch (IOException e) {
320:                    throw new CMSException(
321:                            "can't process mime object to create signature.", e);
322:                } catch (SignatureException e) {
323:                    throw new CMSException(
324:                            "invalid signature format in message: "
325:                                    + e.getMessage(), e);
326:                }
327:            }
328:
329:            private boolean isNull(DEREncodable o) {
330:                return (o instanceof  ASN1Null) || (o == null);
331:            }
332:
333:            private DigestInfo derDecode(byte[] encoding) throws IOException {
334:                if (encoding[0] != (DERTags.CONSTRUCTED | DERTags.SEQUENCE)) {
335:                    throw new IOException("not a digest info object");
336:                }
337:
338:                ASN1InputStream aIn = new ASN1InputStream(encoding);
339:
340:                return new DigestInfo((ASN1Sequence) aIn.readObject());
341:            }
342:
343:            private boolean verifyDigest(byte[] digest, PublicKey key,
344:                    byte[] signature, String sigProvider)
345:                    throws NoSuchAlgorithmException, NoSuchProviderException,
346:                    CMSException {
347:                String algorithm = CMSSignedHelper.INSTANCE
348:                        .getEncryptionAlgName(this .getEncryptionAlgOID());
349:
350:                try {
351:                    if (algorithm.equals("RSA")) {
352:                        Cipher c;
353:                        if (sigProvider != null) {
354:                            c = Cipher.getInstance("RSA/ECB/PKCS1Padding",
355:                                    sigProvider);
356:                        } else {
357:                            c = Cipher.getInstance("RSA/ECB/PKCS1Padding");
358:                        }
359:
360:                        c.init(Cipher.DECRYPT_MODE, key);
361:
362:                        DigestInfo digInfo = derDecode(c.doFinal(signature));
363:
364:                        if (!digInfo.getAlgorithmId().getObjectId().equals(
365:                                digestAlgorithm.getObjectId())) {
366:                            return false;
367:                        }
368:
369:                        if (!isNull(digInfo.getAlgorithmId().getParameters())) {
370:                            return false;
371:                        }
372:
373:                        byte[] sigHash = digInfo.getDigest();
374:
375:                        return MessageDigest.isEqual(digest, sigHash);
376:                    } else if (algorithm.equals("DSA")) {
377:                        Signature sig;
378:                        if (sigProvider != null) {
379:                            sig = Signature.getInstance("NONEwithDSA",
380:                                    sigProvider);
381:                        } else {
382:                            sig = Signature.getInstance("NONEwithDSA",
383:                                    sigProvider);
384:                        }
385:
386:                        sig.initVerify(key);
387:
388:                        sig.update(digest);
389:
390:                        return sig.verify(signature);
391:                    } else {
392:                        throw new CMSException("algorithm: " + algorithm
393:                                + " not supported in base signatures.");
394:                    }
395:                } catch (NoSuchAlgorithmException e) {
396:                    throw e;
397:                } catch (NoSuchProviderException e) {
398:                    throw e;
399:                } catch (GeneralSecurityException e) {
400:                    throw new CMSException("Exception processing signature: "
401:                            + e, e);
402:                } catch (IOException e) {
403:                    throw new CMSException(
404:                            "Exception decoding signature: " + e, e);
405:                }
406:            }
407:
408:            /**
409:             * verify that the given public key succesfully handles and confirms the
410:             * signature associated with this signer.
411:             */
412:            public boolean verify(PublicKey key, String sigProvider)
413:                    throws NoSuchAlgorithmException, NoSuchProviderException,
414:                    CMSException {
415:                return doVerify(key, this .getSignedAttributes(), sigProvider);
416:            }
417:
418:            /**
419:             * verify that the given certificate succesfully handles and confirms
420:             * the signature associated with this signer and, if a signingTime
421:             * attribute is available, that the certificate was valid at the time the
422:             * signature was generated.
423:             */
424:            public boolean verify(X509Certificate cert, String sigProvider)
425:                    throws NoSuchAlgorithmException, NoSuchProviderException,
426:                    CertificateExpiredException,
427:                    CertificateNotYetValidException, CMSException {
428:                AttributeTable attr = this .getSignedAttributes();
429:
430:                if (attr != null) {
431:                    Attribute t = attr.get(CMSAttributes.signingTime);
432:
433:                    if (t != null) {
434:                        Time time = Time.getInstance(t.getAttrValues()
435:                                .getObjectAt(0).getDERObject());
436:
437:                        cert.checkValidity(time.getDate());
438:                    }
439:                }
440:
441:                return doVerify(cert.getPublicKey(), attr, sigProvider);
442:            }
443:
444:            /**
445:             * Return the base ASN.1 CMS structure that this object contains.
446:             * 
447:             * @return an object containing a CMS SignerInfo structure.
448:             */
449:            public SignerInfo toSignerInfo() {
450:                return info;
451:            }
452:
453:            /**
454:             * Return a signer information object with the passed in unsigned
455:             * attributes replacing the ones that are current associated with
456:             * the object passed in.
457:             * 
458:             * @param signerInformation the signerInfo to be used as the basis.
459:             * @param unsignedAttributes the unsigned attributes to add.
460:             * @return a copy of the original SignerInformationObject with the changed attributes.
461:             */
462:            public static SignerInformation replaceUnsignedAttributes(
463:                    SignerInformation signerInformation,
464:                    AttributeTable unsignedAttributes) {
465:                SignerInfo sInfo = signerInformation.info;
466:                ASN1Set unsignedAttr = null;
467:
468:                if (unsignedAttributes != null) {
469:                    unsignedAttr = new DERSet(unsignedAttributes
470:                            .toASN1EncodableVector());
471:                }
472:
473:                return new SignerInformation(new SignerInfo(sInfo.getSID(),
474:                        sInfo.getDigestAlgorithm(), sInfo
475:                                .getAuthenticatedAttributes(), sInfo
476:                                .getDigestEncryptionAlgorithm(), sInfo
477:                                .getEncryptedDigest(), unsignedAttr),
478:                        signerInformation.contentType,
479:                        signerInformation.content, null);
480:            }
481:        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.