Source Code Cross Referenced for PKCS7SignedData.java in  » Security » Bouncy-Castle » org » bouncycastle » jce » 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.jce 
Source Cross Referenced  Class Diagram Java Document (Java Doc) 


001:        package org.bouncycastle.jce;
002:
003:        import org.bouncycastle.asn1.ASN1EncodableVector;
004:        import org.bouncycastle.asn1.ASN1InputStream;
005:        import org.bouncycastle.asn1.ASN1Sequence;
006:        import org.bouncycastle.asn1.ASN1Set;
007:        import org.bouncycastle.asn1.DERInteger;
008:        import org.bouncycastle.asn1.DERNull;
009:        import org.bouncycastle.asn1.DERObject;
010:        import org.bouncycastle.asn1.DERObjectIdentifier;
011:        import org.bouncycastle.asn1.DEROctetString;
012:        import org.bouncycastle.asn1.DEROutputStream;
013:        import org.bouncycastle.asn1.DERSequence;
014:        import org.bouncycastle.asn1.DERSet;
015:        import org.bouncycastle.asn1.DERTaggedObject;
016:        import org.bouncycastle.asn1.pkcs.ContentInfo;
017:        import org.bouncycastle.asn1.pkcs.IssuerAndSerialNumber;
018:        import org.bouncycastle.asn1.pkcs.PKCSObjectIdentifiers;
019:        import org.bouncycastle.asn1.pkcs.SignedData;
020:        import org.bouncycastle.asn1.pkcs.SignerInfo;
021:        import org.bouncycastle.asn1.x509.AlgorithmIdentifier;
022:        import org.bouncycastle.asn1.x509.CertificateList;
023:        import org.bouncycastle.asn1.x509.X509CertificateStructure;
024:        import org.bouncycastle.asn1.x509.X509Name;
025:        import org.bouncycastle.jce.provider.X509CRLObject;
026:        import org.bouncycastle.jce.provider.X509CertificateObject;
027:
028:        import java.io.ByteArrayInputStream;
029:        import java.io.ByteArrayOutputStream;
030:        import java.io.IOException;
031:        import java.math.BigInteger;
032:        import java.security.InvalidKeyException;
033:        import java.security.NoSuchAlgorithmException;
034:        import java.security.NoSuchProviderException;
035:        import java.security.PrivateKey;
036:        import java.security.Signature;
037:        import java.security.SignatureException;
038:        import java.security.cert.CRL;
039:        import java.security.cert.CRLException;
040:        import java.security.cert.Certificate;
041:        import java.security.cert.CertificateParsingException;
042:        import java.security.cert.X509CRL;
043:        import java.security.cert.X509Certificate;
044:        import java.util.ArrayList;
045:        import java.util.Collection;
046:        import java.util.Enumeration;
047:        import java.util.HashSet;
048:        import java.util.Iterator;
049:        import java.util.Set;
050:
051:        /**
052:         * Represents a PKCS#7 object - specifically the "Signed Data"
053:         * type.
054:         * <p>
055:         * How to use it? To verify a signature, do:
056:         * <pre>
057:         * PKCS7SignedData pkcs7 = new PKCS7SignedData(der_bytes);        // Create it
058:         * pkcs7.update(bytes, 0, bytes.length);                          // Update checksum
059:         * boolean verified = pkcs7.verify();                             // Does it add up?
060:         *
061:         * To sign, do this:
062:         * PKCS7SignedData pkcs7 = new PKCS7SignedData(privKey, certChain, "MD5");
063:         * pkcs7.update(bytes, 0, bytes.length);                          // Update checksum
064:         * pkcs7.sign();                                                  // Create digest
065:         *
066:         * bytes = pkcs7.getEncoded();                                    // Write it somewhere
067:         * </pre>
068:         * <p>
069:         * This class is pretty close to obsolete, for a much better (and more complete)
070:         * implementation of PKCS7 have a look at the org.bouncycastle.cms package.
071:         * @deprecated this class really is obsolete - use the CMS package.
072:         */
073:        public class PKCS7SignedData implements  PKCSObjectIdentifiers {
074:            private int version, signerversion;
075:            private Set digestalgos;
076:            private Collection certs, crls;
077:            private X509Certificate signCert;
078:            private byte[] digest;
079:            private String digestAlgorithm, digestEncryptionAlgorithm;
080:            private Signature sig;
081:            private transient PrivateKey privKey;
082:
083:            private final String ID_PKCS7_DATA = "1.2.840.113549.1.7.1";
084:            private final String ID_PKCS7_SIGNED_DATA = "1.2.840.113549.1.7.2";
085:            private final String ID_MD5 = "1.2.840.113549.2.5";
086:            private final String ID_MD2 = "1.2.840.113549.2.2";
087:            private final String ID_SHA1 = "1.3.14.3.2.26";
088:            private final String ID_RSA = "1.2.840.113549.1.1.1";
089:            private final String ID_DSA = "1.2.840.10040.4.1";
090:
091:            /**
092:             * Read an existing PKCS#7 object from a DER encoded byte array using
093:             * the BC provider.
094:             */
095:            public PKCS7SignedData(byte[] in) throws SecurityException,
096:                    CRLException, InvalidKeyException, NoSuchProviderException,
097:                    NoSuchAlgorithmException {
098:                this (in, "BC");
099:            }
100:
101:            /**
102:             * Read an existing PKCS#7 object from a DER encoded byte array 
103:             */
104:            public PKCS7SignedData(byte[] in, String provider)
105:                    throws SecurityException, CRLException,
106:                    InvalidKeyException, NoSuchProviderException,
107:                    NoSuchAlgorithmException {
108:                ASN1InputStream din = new ASN1InputStream(
109:                        new ByteArrayInputStream(in));
110:
111:                //
112:                // Basic checks to make sure it's a PKCS#7 SignedData Object
113:                //
114:                DERObject pkcs;
115:
116:                try {
117:                    pkcs = din.readObject();
118:                } catch (IOException e) {
119:                    throw new SecurityException(
120:                            "can't decode PKCS7SignedData object");
121:                }
122:
123:                if (!(pkcs instanceof  ASN1Sequence)) {
124:                    throw new SecurityException(
125:                            "Not a valid PKCS#7 object - not a sequence");
126:                }
127:
128:                ContentInfo content = ContentInfo.getInstance(pkcs);
129:
130:                if (!content.getContentType().equals(signedData)) {
131:                    throw new SecurityException(
132:                            "Not a valid PKCS#7 signed-data object - wrong header "
133:                                    + content.getContentType().getId());
134:                }
135:
136:                SignedData data = SignedData.getInstance(content.getContent());
137:
138:                certs = new ArrayList();
139:
140:                if (data.getCertificates() != null) {
141:                    Enumeration ec = ASN1Set
142:                            .getInstance(data.getCertificates()).getObjects();
143:
144:                    while (ec.hasMoreElements()) {
145:                        try {
146:                            certs.add(new X509CertificateObject(
147:                                    X509CertificateStructure.getInstance(ec
148:                                            .nextElement())));
149:                        } catch (CertificateParsingException e) {
150:                            throw new SecurityException(e.toString());
151:                        }
152:                    }
153:                }
154:
155:                crls = new ArrayList();
156:
157:                if (data.getCRLs() != null) {
158:                    Enumeration ec = ASN1Set.getInstance(data.getCRLs())
159:                            .getObjects();
160:                    while (ec.hasMoreElements()) {
161:                        crls.add(new X509CRLObject(CertificateList
162:                                .getInstance(ec.nextElement())));
163:                    }
164:                }
165:
166:                version = data.getVersion().getValue().intValue();
167:
168:                //
169:                // Get the digest algorithm
170:                //
171:                digestalgos = new HashSet();
172:                Enumeration e = data.getDigestAlgorithms().getObjects();
173:
174:                while (e.hasMoreElements()) {
175:                    ASN1Sequence s = (ASN1Sequence) e.nextElement();
176:                    DERObjectIdentifier o = (DERObjectIdentifier) s
177:                            .getObjectAt(0);
178:                    digestalgos.add(o.getId());
179:                }
180:
181:                //
182:                // Get the SignerInfo
183:                //
184:                ASN1Set signerinfos = data.getSignerInfos();
185:                if (signerinfos.size() != 1) {
186:                    throw new SecurityException(
187:                            "This PKCS#7 object has multiple SignerInfos - only one is supported at this time");
188:                }
189:
190:                SignerInfo signerInfo = SignerInfo.getInstance(signerinfos
191:                        .getObjectAt(0));
192:
193:                signerversion = signerInfo.getVersion().getValue().intValue();
194:
195:                IssuerAndSerialNumber isAnds = signerInfo
196:                        .getIssuerAndSerialNumber();
197:
198:                //
199:                // Get the signing certificate
200:                //
201:                BigInteger serialNumber = isAnds.getCertificateSerialNumber()
202:                        .getValue();
203:                X509Principal issuer = new X509Principal(isAnds.getName());
204:
205:                for (Iterator i = certs.iterator(); i.hasNext();) {
206:                    X509Certificate cert = (X509Certificate) i.next();
207:                    if (serialNumber.equals(cert.getSerialNumber())
208:                            && issuer.equals(cert.getIssuerDN())) {
209:                        signCert = cert;
210:                        break;
211:                    }
212:                }
213:
214:                if (signCert == null) {
215:                    throw new SecurityException(
216:                            "Can't find signing certificate with serial "
217:                                    + serialNumber.toString(16));
218:                }
219:
220:                digestAlgorithm = signerInfo.getDigestAlgorithm().getObjectId()
221:                        .getId();
222:
223:                digest = signerInfo.getEncryptedDigest().getOctets();
224:                digestEncryptionAlgorithm = signerInfo
225:                        .getDigestEncryptionAlgorithm().getObjectId().getId();
226:
227:                sig = Signature.getInstance(getDigestAlgorithm(), provider);
228:
229:                sig.initVerify(signCert.getPublicKey());
230:            }
231:
232:            /**
233:             * Create a new PKCS#7 object from the specified key using the BC provider.
234:             *
235:             * @param privKey the private key to be used for signing.
236:             * @param certChain the certificate chain associated with the private key.
237:             * @param hashAlgorithm the hashing algorithm used to compute the message digest. Must be "MD5", "MD2", "SHA1" or "SHA"
238:             */
239:            public PKCS7SignedData(PrivateKey privKey, Certificate[] certChain,
240:                    String hashAlgorithm) throws SecurityException,
241:                    InvalidKeyException, NoSuchProviderException,
242:                    NoSuchAlgorithmException {
243:                this (privKey, certChain, hashAlgorithm, "BC");
244:            }
245:
246:            /**
247:             * Create a new PKCS#7 object from the specified key.
248:             *
249:             * @param privKey the private key to be used for signing.
250:             * @param certChain the certificate chain associated with the private key.
251:             * @param hashAlgorithm the hashing algorithm used to compute the message digest. Must be "MD5", "MD2", "SHA1" or "SHA"
252:             * @param provider the provider to use.
253:             */
254:            public PKCS7SignedData(PrivateKey privKey, Certificate[] certChain,
255:                    String hashAlgorithm, String provider)
256:                    throws SecurityException, InvalidKeyException,
257:                    NoSuchProviderException, NoSuchAlgorithmException {
258:                this (privKey, certChain, null, hashAlgorithm, provider);
259:            }
260:
261:            /**
262:             * Create a new PKCS#7 object from the specified key.
263:             *
264:             * @param privKey the private key to be used for signing.
265:             * @param certChain the certificate chain associated with the private key.
266:             * @param crlList the crl list associated with the private key.
267:             * @param hashAlgorithm the hashing algorithm used to compute the message digest. Must be "MD5", "MD2", "SHA1" or "SHA"
268:             * @param provider the provider to use.
269:             */
270:            public PKCS7SignedData(PrivateKey privKey, Certificate[] certChain,
271:                    CRL[] crlList, String hashAlgorithm, String provider)
272:                    throws SecurityException, InvalidKeyException,
273:                    NoSuchProviderException, NoSuchAlgorithmException {
274:                this .privKey = privKey;
275:
276:                if (hashAlgorithm.equals("MD5")) {
277:                    digestAlgorithm = ID_MD5;
278:                } else if (hashAlgorithm.equals("MD2")) {
279:                    digestAlgorithm = ID_MD2;
280:                } else if (hashAlgorithm.equals("SHA")) {
281:                    digestAlgorithm = ID_SHA1;
282:                } else if (hashAlgorithm.equals("SHA1")) {
283:                    digestAlgorithm = ID_SHA1;
284:                } else {
285:                    throw new NoSuchAlgorithmException(
286:                            "Unknown Hash Algorithm " + hashAlgorithm);
287:                }
288:
289:                version = signerversion = 1;
290:                certs = new ArrayList();
291:                crls = new ArrayList();
292:                digestalgos = new HashSet();
293:                digestalgos.add(digestAlgorithm);
294:
295:                //
296:                // Copy in the certificates and crls used to sign the private key.
297:                //
298:                signCert = (X509Certificate) certChain[0];
299:                for (int i = 0; i < certChain.length; i++) {
300:                    certs.add(certChain[i]);
301:                }
302:
303:                if (crlList != null) {
304:                    for (int i = 0; i < crlList.length; i++) {
305:                        crls.add(crlList[i]);
306:                    }
307:                }
308:
309:                //
310:                // Now we have private key, find out what the digestEncryptionAlgorithm is.
311:                //
312:                digestEncryptionAlgorithm = privKey.getAlgorithm();
313:                if (digestEncryptionAlgorithm.equals("RSA")) {
314:                    digestEncryptionAlgorithm = ID_RSA;
315:                } else if (digestEncryptionAlgorithm.equals("DSA")) {
316:                    digestEncryptionAlgorithm = ID_DSA;
317:                } else {
318:                    throw new NoSuchAlgorithmException("Unknown Key Algorithm "
319:                            + digestEncryptionAlgorithm);
320:                }
321:
322:                sig = Signature.getInstance(getDigestAlgorithm(), provider);
323:
324:                sig.initSign(privKey);
325:            }
326:
327:            /**
328:             * Get the algorithm used to calculate the message digest
329:             */
330:            public String getDigestAlgorithm() {
331:                String da = digestAlgorithm;
332:                String dea = digestEncryptionAlgorithm;
333:
334:                if (digestAlgorithm.equals(ID_MD5)) {
335:                    da = "MD5";
336:                } else if (digestAlgorithm.equals(ID_MD2)) {
337:                    da = "MD2";
338:                } else if (digestAlgorithm.equals(ID_SHA1)) {
339:                    da = "SHA1";
340:                }
341:
342:                if (digestEncryptionAlgorithm.equals(ID_RSA)) {
343:                    dea = "RSA";
344:                } else if (digestEncryptionAlgorithm.equals(ID_DSA)) {
345:                    dea = "DSA";
346:                }
347:
348:                return da + "with" + dea;
349:            }
350:
351:            /**
352:             * Resets the PKCS7SignedData object to it's initial state, ready
353:             * to sign or verify a new buffer.
354:             */
355:            public void reset() {
356:                try {
357:                    if (privKey == null) {
358:                        sig.initVerify(signCert.getPublicKey());
359:                    } else {
360:                        sig.initSign(privKey);
361:                    }
362:                } catch (Exception e) {
363:                    throw new RuntimeException(e.toString());
364:                }
365:            }
366:
367:            /**
368:             * Get the X.509 certificates associated with this PKCS#7 object
369:             */
370:            public Certificate[] getCertificates() {
371:                return (X509Certificate[]) certs
372:                        .toArray(new X509Certificate[certs.size()]);
373:            }
374:
375:            /**
376:             * Get the X.509 certificate revocation lists associated with this PKCS#7 object
377:             */
378:            public Collection getCRLs() {
379:                return crls;
380:            }
381:
382:            /**
383:             * Get the X.509 certificate actually used to sign the digest.
384:             */
385:            public X509Certificate getSigningCertificate() {
386:                return signCert;
387:            }
388:
389:            /**
390:             * Get the version of the PKCS#7 object. Always 1
391:             */
392:            public int getVersion() {
393:                return version;
394:            }
395:
396:            /**
397:             * Get the version of the PKCS#7 "SignerInfo" object. Always 1
398:             */
399:            public int getSigningInfoVersion() {
400:                return signerversion;
401:            }
402:
403:            /**
404:             * Update the digest with the specified byte. This method is used both for signing and verifying
405:             */
406:            public void update(byte buf) throws SignatureException {
407:                sig.update(buf);
408:            }
409:
410:            /**
411:             * Update the digest with the specified bytes. This method is used both for signing and verifying
412:             */
413:            public void update(byte[] buf, int off, int len)
414:                    throws SignatureException {
415:                sig.update(buf, off, len);
416:            }
417:
418:            /**
419:             * Verify the digest
420:             */
421:            public boolean verify() throws SignatureException {
422:                return sig.verify(digest);
423:            }
424:
425:            /**
426:             * Get the "issuer" from the TBSCertificate bytes that are passed in
427:             */
428:            private DERObject getIssuer(byte[] enc) {
429:                try {
430:                    ASN1InputStream in = new ASN1InputStream(
431:                            new ByteArrayInputStream(enc));
432:                    ASN1Sequence seq = (ASN1Sequence) in.readObject();
433:                    return (DERObject) seq
434:                            .getObjectAt(seq.getObjectAt(0) instanceof  DERTaggedObject ? 3
435:                                    : 2);
436:                } catch (IOException e) {
437:                    throw new Error("IOException reading from ByteArray: " + e);
438:                }
439:            }
440:
441:            /**
442:             * return the bytes for the PKCS7SignedData object.
443:             */
444:            public byte[] getEncoded() {
445:                try {
446:
447:                    digest = sig.sign();
448:
449:                    // Create the set of Hash algorithms. I've assumed this is the
450:                    // set of all hash agorithms used to created the digest in the
451:                    // "signerInfo" structure. I may be wrong.
452:                    //
453:                    ASN1EncodableVector v = new ASN1EncodableVector();
454:                    for (Iterator i = digestalgos.iterator(); i.hasNext();) {
455:                        AlgorithmIdentifier a = new AlgorithmIdentifier(
456:                                new DERObjectIdentifier((String) i.next()),
457:                                null);
458:
459:                        v.add(a);
460:                    }
461:
462:                    DERSet algos = new DERSet(v);
463:
464:                    // Create the contentInfo. Empty, I didn't implement this bit
465:                    //
466:                    DERSequence contentinfo = new DERSequence(
467:                            new DERObjectIdentifier(ID_PKCS7_DATA));
468:
469:                    // Get all the certificates
470:                    //
471:                    v = new ASN1EncodableVector();
472:                    for (Iterator i = certs.iterator(); i.hasNext();) {
473:                        ASN1InputStream tempstream = new ASN1InputStream(
474:                                new ByteArrayInputStream(((X509Certificate) i
475:                                        .next()).getEncoded()));
476:                        v.add(tempstream.readObject());
477:                    }
478:
479:                    DERSet dercertificates = new DERSet(v);
480:
481:                    // Create signerinfo structure.
482:                    //
483:                    ASN1EncodableVector signerinfo = new ASN1EncodableVector();
484:
485:                    // Add the signerInfo version
486:                    //
487:                    signerinfo.add(new DERInteger(signerversion));
488:
489:                    IssuerAndSerialNumber isAnds = new IssuerAndSerialNumber(
490:                            new X509Name((ASN1Sequence) getIssuer(signCert
491:                                    .getTBSCertificate())), new DERInteger(
492:                                    signCert.getSerialNumber()));
493:                    signerinfo.add(isAnds);
494:
495:                    // Add the digestAlgorithm
496:                    //
497:                    signerinfo.add(new AlgorithmIdentifier(
498:                            new DERObjectIdentifier(digestAlgorithm),
499:                            new DERNull()));
500:
501:                    //
502:                    // Add the digestEncryptionAlgorithm
503:                    //
504:                    signerinfo.add(new AlgorithmIdentifier(
505:                            new DERObjectIdentifier(digestEncryptionAlgorithm),
506:                            new DERNull()));
507:
508:                    //
509:                    // Add the digest
510:                    //
511:                    signerinfo.add(new DEROctetString(digest));
512:
513:                    //
514:                    // Finally build the body out of all the components above
515:                    //
516:                    ASN1EncodableVector body = new ASN1EncodableVector();
517:                    body.add(new DERInteger(version));
518:                    body.add(algos);
519:                    body.add(contentinfo);
520:                    body.add(new DERTaggedObject(false, 0, dercertificates));
521:
522:                    if (crls.size() > 0) {
523:                        v = new ASN1EncodableVector();
524:                        for (Iterator i = crls.iterator(); i.hasNext();) {
525:                            ASN1InputStream t = new ASN1InputStream(
526:                                    new ByteArrayInputStream(((X509CRL) i
527:                                            .next()).getEncoded()));
528:                            v.add(t.readObject());
529:                        }
530:                        DERSet dercrls = new DERSet(v);
531:                        body.add(new DERTaggedObject(false, 1, dercrls));
532:                    }
533:
534:                    // Only allow one signerInfo
535:                    //
536:                    body.add(new DERSet(new DERSequence(signerinfo)));
537:
538:                    // Now we have the body, wrap it in it's PKCS7Signed shell
539:                    // and return it
540:                    //
541:                    ASN1EncodableVector whole = new ASN1EncodableVector();
542:                    whole.add(new DERObjectIdentifier(ID_PKCS7_SIGNED_DATA));
543:                    whole.add(new DERTaggedObject(0, new DERSequence(body)));
544:
545:                    ByteArrayOutputStream bOut = new ByteArrayOutputStream();
546:
547:                    DEROutputStream dout = new DEROutputStream(bOut);
548:                    dout.writeObject(new DERSequence(whole));
549:                    dout.close();
550:
551:                    return bOut.toByteArray();
552:                } catch (Exception e) {
553:                    throw new RuntimeException(e.toString());
554:                }
555:            }
556:        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.