001: package org.bouncycastle.asn1.test;
002:
003: import org.bouncycastle.asn1.ASN1InputStream;
004: import org.bouncycastle.asn1.ASN1OctetString;
005: import org.bouncycastle.asn1.ASN1OutputStream;
006: import org.bouncycastle.asn1.ASN1Sequence;
007: import org.bouncycastle.asn1.BERConstructedOctetString;
008: import org.bouncycastle.asn1.DERSequence;
009: import org.bouncycastle.asn1.pkcs.AuthenticatedSafe;
010: import org.bouncycastle.asn1.pkcs.ContentInfo;
011: import org.bouncycastle.asn1.pkcs.EncryptedData;
012: import org.bouncycastle.asn1.pkcs.EncryptedPrivateKeyInfo;
013: import org.bouncycastle.asn1.pkcs.MacData;
014: import org.bouncycastle.asn1.pkcs.PKCSObjectIdentifiers;
015: import org.bouncycastle.asn1.pkcs.Pfx;
016: import org.bouncycastle.asn1.pkcs.SafeBag;
017: import org.bouncycastle.asn1.x509.AlgorithmIdentifier;
018: import org.bouncycastle.asn1.x509.DigestInfo;
019: import org.bouncycastle.util.encoders.Base64;
020: import org.bouncycastle.util.test.SimpleTestResult;
021: import org.bouncycastle.util.test.Test;
022: import org.bouncycastle.util.test.TestResult;
023:
024: import java.io.ByteArrayInputStream;
025: import java.io.ByteArrayOutputStream;
026:
027: public class PKCS12Test implements Test {
028: byte[] pkcs12 = Base64
029: .decode("MIACAQMwgAYJKoZIhvcNAQcBoIAkgASCA+gwgDCABgkqhkiG9w0BBwGggCSA"
030: + "BIIDRDCCA0AwggM8BgsqhkiG9w0BDAoBAqCCArEwggKtMCcGCiqGSIb3DQEM"
031: + "AQMwGQQUFlnNVpQoEHc+J3UEGxARipkHu5kCAWQEggKAAH9tmy40lly6QDoc"
032: + "1TfmY9y2qysD+lrgk+dnxP04RfoJfycTRDeaz2sPLImZtio9nsqCFqtzU/sl"
033: + "eWigbH34BpKU1sC0Gq1cyik0GO65sW95S6YjKtGcGOBfQCPk1oQjfiqnfU3G"
034: + "oeOaG3COQJukMFj8unv55u0xbX1hwO8SsZmr9RjPzLrVaeY6BP5+CCzOKBaj"
035: + "GxneIDqnQW7/kBIVWK7M+JXGdgQyiKhD6NvXL/zD8oKEne0nIX7IokQuWEn6"
036: + "8Sglv5OSclsSdvHTk57bCuV5lVzoIzczA4J/LZWdrtITeVefBLQSalBzpRde"
037: + "rSTMj485z2x5ChizhjE627/KQ5vkKQkQVqXYYXVyeTvKZRpL7vz13C4DUCwN"
038: + "im1XvNSCNebXS1yHJRtcONDhGJN3UsrVjHr+2kCfE5SCEeSU/dqgNLuLa1tk"
039: + "5+jwZFNj/HjO88wlOwPCol1uuJjDpaEW7dxu5qsVSfZhEXWHs8rZAMttFMzi"
040: + "yxsEkZe8kqngRbNJOY6KpppYedsMWDusUJGfIHo+8zymiw3gv/z+lmFOlDGt"
041: + "CKMk9Es/MgfjpbfhbTVYHOBKS6Qyrz7LdTuBMI8XdsZMuN+Uf73690ggLmKW"
042: + "IELUg8h1RX0ra2n6jOc/1rnebAifMhiMkL1ABQvqOobfOrG/9h9XcXoi64Qr"
043: + "htc3T7yMAHafBX5KUcNkbcn6kssYhpvd8bPADoLBnbx3GxGh/uziB0zKQEI0"
044: + "GnaY4SL7aR4C5xNNi41lYtsR6ohKyfPEGslhrhd4axx0cKxC2sHgVl0k+r8B"
045: + "8Vu44XHbW8LqdspjOHN9qg2erES1Dvgj05SfHDup+V6a3ogJo2YKXOiu3DF4"
046: + "MFEGCSqGSIb3DQEJFDFEHkIARABhAHYAaQBkACAARwAuACAASABvAG8AawAn"
047: + "AHMAIABWAGUAcgBpAFMAaQBnAG4ALAAgAEkAbgBjAC4AIABJAEQwIwYJKoZI"
048: + "hvcNAQkVMRYEFKEcMJ798oZLFkH0OnpbUBnrTLgWAAAAAAAAMIAGCSqGSIb3"
049: + "DQEHBqCAMIACAQAwgAYJKoZIhvcNAQcBMCcGCiqGSIb3DQEMAQYwGQQUTErH"
050: + "kWZ8nBXZYWO53FH4yqRZZsECAWSggASCDGCreuCr6/azcOv5w04bN3jkg4G2"
051: + "dsvTPAjL8bichaEOQCykhuNPt1dv3FsjUsdFC550K0+Y48RyBIID6JTiN9Gj"
052: + "K+a5aLPaXgTRdY74Toof1hYtZ4DIcVyq25LezVQHoe/++pAgEpWjqHTxVDIv"
053: + "YFAgT2oDB+2vkeXM61XnNWOjwCY3pXpk/VGjyN4USkD7Q/Y6tPjQOywvQE7c"
054: + "Ab1z62k9iMia7Yk/qmh+zJu4SSneo0/RLLdMZOlGZv89MResVG038TC8MTA9"
055: + "Uf+wDRcS20d7XDbTaBAgju8TpFIw5/lbDi0feUVlk6L+jkT1ktaTc1Pwtxn7"
056: + "psXMFW6HAWB4exOi09297R9BCOQX6vcetK/iA/3jIC6NuTdizYof0DWetdGy"
057: + "haIkMiEnERYE3unJocH4fq585Rw6mE+BYssPVPkVWZZInF3l69bKduuxsQt+"
058: + "pcApgBVsTjsU+1FOiUxuW2wWKi70RcQprPv5Ef1A5FRNxPFp+7IzLNlE4qCo"
059: + "wvC6NTpeuRw3aGsXSfqHmSddrHugNPmghNgG5lv1Ef7A8MUuyp8fyjAgxCDk"
060: + "4Hpb8PCHGj5t//Fr6Cd0MygJMIFQmv4kUd2LVHxQ9A9WFNCqTz/nBe+ZRLJL"
061: + "NghTv6gGpjGJiBnXYv6Sod2fs+5J2GIvex4qbdh6gzZIU2YTAwpj6Aca3SjA"
062: + "X8+m8AXt2SC3Z6T5+m8SxyiNp2P511paV/TZKtLWXQGKeEX1JXhQkaM6Q5W/"
063: + "IhSgC8/gppk1gbIraBqrW8bEnGBnC03wi0OnMz3ohM4CVHyaW3dQquT2+u6F"
064: + "8VeGXAYHU022NkrpPl/VlfNNEAyisU2+oJqpPZkqL6FsDWF3k6Fq2jXBLL+/"
065: + "a0WA82jIpgjNeXze/cgoHtU023V9E9Qcu+5nPBYdCTR4sRxvHLANii0W8lPv"
066: + "tvU5XO1UsEjHDfKL4E1bhGzGpb/OU5yg/98EN95r/xdFL5G+XVyHeR0UtkcB"
067: + "IuvyBdhkwoprCjkcgLZe8FPIBNw84HRe7Ye6f2gDW/F5uej6rBehJS1VFvCh"
068: + "DXzkajGmK40Gc2APS1/1vZqPu68polgw9dT84rem36PLEOq4KuU7n4QE0g7T"
069: + "YR2G8+4FNgQTjjg/qw3lX+sj6yLn1lYt1dOVvkiM8i8tdZg/3pCKKAW1uV7a"
070: + "astlBxVSkFfn1BrFTc2oFGkTrlUg90a+parOfGHTfDiaHX8ouEg63fk0+Xdi"
071: + "FCarXsqHNPDbpmWLKw8TAmdeneGipyScntJJk4ajy+jROQBgGew3ofOmfkqm"
072: + "oJFNwUvKOXN2ucViLZgsdK/7YgV1OR7oiTh8knQNPk3d5fRYSMFf9GJTjQRV"
073: + "y2CLdICAVzvrUXf9k7miWYkjIp2/HGD7pOH018sX9MrpfJKqvdPFOssZiFd0"
074: + "I2FUbgcEggPotvnT0XoabEiurTm8EPPpw66NKmK/H1kQL0hEtdIazPxfLmm/"
075: + "ZUDokwa7d4bE3BwFh0weQfEvMzJu6Y5E7ir2MqD33XaGMOGys1nst1SPPyDB"
076: + "WpOWD9w7Ng3yU1JVzqFWuVXaXDYbfnlG7AGevKF5PYNZj/RIQBBf5Xle9hTd"
077: + "c9CtxPkrsJwA8DeAwKl2WIfbXGzAYLSnXoYUcoTkWn/O81BlUFgAXv80gLe8"
078: + "NUrH7bhsnyGaPY953NyDk8IWUYrsn/sXvxTy5B0/7/WGMh3CSZrLX3p7TcFY"
079: + "yBrL6SRas4q9rrcwuhBq0tUUbbgWi92nhZl4bOGmx7ehHnwuUId2HWXyVGoB"
080: + "qToee/2E4PZFxSZwKCY6dahswFq5QGDrQKN2/qpOLZcJib6SvSGyEZl2pqr0"
081: + "lqk7tVPzBkN/4uP0qrcbZCDbGW6IXwu3RGMRehqj/HEJcs92lZKfVrk/U07X"
082: + "MBAiQHqV+kLw7kStECR/MGJG1c0xhqqBrf0W74+LpJiv/Q9iFNdWbXvE/cAk"
083: + "G7+OTUABd2kI88uA43T0UoRuPOi5KnLuD3AG+7IuyGyP69Xncd4u0srMg2fn"
084: + "DiLLZUy6vWmxwRFsSMCEfQNLtZaggukoPIihQvbX3mQS9izwLs6D89WtEcZ5"
085: + "6DVbIlUqUinnNKsT8vW1DZo5FMJkUxB666YIPVmkQbbJOEUU89dZg5Gw0og6"
086: + "rn4irEr4xHFdx+S7iqJXhzs9THg/9e4/k8KQ136z7LALOqDookcSdBzW6H8c"
087: + "STjs4qKQyNimsLB90mEuIEApzhseAaLFl+kgORGJv/2a+uoukZchMsJ98MVo"
088: + "sEPS1oBXJl2m9AshkWfON2GDeJatgcw6CyC1mSx++Gg602ZKUZZUaWxkz1Sw"
089: + "zTj3nhiJe+SZsdfxhsojNq7zfxqgY/Rq7BwvphU3StjnxvkB4rTkbmbiGOBO"
090: + "cvTFg4yOtQGRcifk2/XH/bgYiPqQrYSXpO3WRASV005RaSGufcpTtj3YlHGe"
091: + "8FUgZfDtfiGezhNET9KO3/Q0i34bGEpoIb/9uOWH4ZHULIlfdSm1ynV50nE4"
092: + "mJTXccrF6BE80KZI5GWGhqXdfPFaHTK1S20+XCw7bRJCGeiwVxvGfB+C0SZ4"
093: + "ndtqx165dKG5JwFukcygiIZN6foh0/PhwzmFxmPtZuPQt9dtuIQ35Y7PSDsy"
094: + "IH2Ot0Hh0YIN99lHJ6n9HomSjpwcgDXGssEuevbpz27u/MI/Uhq4Gfx0k5RF"
095: + "0pcRYtk1dYSx44a+8WgqZLF8DUNtyjSE/H8P5iGa6tqOl7kNyeeEkfoTtKst"
096: + "asGFwL4Qxxus4GC7repyVi7IJgSCA+iopiqKQJ2IqUHvoIEuD//sZooDx0Je"
097: + "oFRO5VakkTO6WHd8JpOOEU2f6Zjg++HdIl0QK7xcUaRH075LzEfqgn1vyw6J"
098: + "N6ex8D76sf/nAy01NvDPij48Z50XDwXu4kJGJvv0AJwId8BpjziBF0j3K/DI"
099: + "YOOpd6nW4EvdivCgaCnxqlIU/u1OP4BwpO+AUjJh6RKlKviGihQpi103DFhR"
100: + "yXNDhh55pqgCCCuNeEB+ovRt7UxzlGAVRSxJh1Zbjp/+iQun0E32RlSR4Diz"
101: + "p5vDk8NBZpIiKRqI+8GWZc3G1igp7dvViTLw4OdWMKwhccV5+3Ll/W72aNVm"
102: + "azYUoYOVn+OYS1NJkER0tjFOCozRGm5hfkxGlP+02wbH5uu/AQoJMqWIxT6l"
103: + "46IWC24lmAnDCXuM+gWmwUvyXLwuBdejVK8iG1Lnfg1qztoLpYRbBROgRdpt"
104: + "2cbPRm+9seqrth3eJbtmxCvuh3bZ3pR2e0/r5Tob/fDcOc5Kp+j4ndXWkwpa"
105: + "OuH1yxam7zNJR+mcYp1Wiujia5qIeY1QCAEY5QgAWaSHtjlEprwUuootA2Xm"
106: + "V7D8Vsr9BValhm9zMKj6IzsPmM+HZJWlhHcoucuAmPK6Lnys3Kv/mbkSgNOq"
107: + "fJDY901veFfKeqiCbAm6hZjNWoQDNJKFhjXUALrcOv9VCFPA3bMW3Xul/sB4"
108: + "Mq595e+x/1HkNOgZorBv97C6X7ENVDaAFcyZvrRU/ZeDnvFhisfxS4EJhzxl"
109: + "cWWnQhzD+ur1FTTlkmUFzgoB/rW+i3XigiHOuRRnkcoMy1uV17rwH8eELHJu"
110: + "Yni5vu2QUaD4jNEhliE2XCsn8Sm6bcXnfzBa7FXC39QvAcdJHzqcD6iIwjIz"
111: + "hKLu+/XoWFMFFNsgV78AwzPAn6TRya8LLCYPoIZkEP4qBoeZtUZ8PIS/Y7M9"
112: + "QStMwa/NI9SPswb3iScTGvor/obUEQS4QM6mVxFMpQWfwJfyU6jingX4EHRE"
113: + "mqvZ3ehzU8ZLOdKzRKuk022YDT7hwEQ+VL0Fg0Ld9oexqT96nQpUTHZtDRMV"
114: + "iTuJoUYTneDs2c9tsY4mWBqamZQSfTegj4sLMZagkuSUp/SpPM2zSGuD3nY6"
115: + "u3553gIM9jYhvLBEXwjGudVCwMd3bqo/4EhnKb2PcwUzdaMkipQlNteHZjBT"
116: + "1ici63xjJva+di0qTV+W9cyYyHwg1927X2qcMh06BhbHlcXQKbgmbL18KJEt"
117: + "K+GGhGNkP7mtPyHHgBb6vref/z8p7oxT2CG+oBuN/z+xQoYfe9c4IC3e/kNN"
118: + "DIoyYvPyEzAdfMS2aL8qDxzc5GH9UE9kcusJ/2dNEFTzBH2GK1CItL3IACv/"
119: + "LwX1SkI0w7oIQTL127CSnuTrUUkvJ/+rOYScQTMD/ntZPdLdu2ffszg3SzhN"
120: + "ELgojK8ss1OBlruWRHw/fP736Nx8MNsuOvXMnO8lruz+uyuEhF3BLv96oTcg"
121: + "XVHdWhPmOoqNdBQdRgAAAAAAAAAAAAAAAAAAAAAAADA8MCEwCQYFKw4DAhoF"
122: + "AAQUJMZn7MEKv4vW/+voCVyHBa6B0EMEFJOzH/BEjRtNNsZWlo/4L840aE5r"
123: + "AgFkAAA=");
124:
125: private boolean isSameAs(byte[] a, byte[] b) {
126: if (a.length != b.length) {
127: return false;
128: }
129:
130: for (int i = 0; i != a.length; i++) {
131: if (a[i] != b[i]) {
132: return false;
133: }
134: }
135:
136: return true;
137: }
138:
139: public TestResult perform() {
140: try {
141: ASN1InputStream aIn = new ASN1InputStream(
142: new ByteArrayInputStream(pkcs12));
143: ASN1Sequence obj = (ASN1Sequence) aIn.readObject();
144: Pfx bag = new Pfx(obj);
145: ContentInfo info = bag.getAuthSafe();
146: MacData mData = bag.getMacData();
147: DigestInfo dInfo = mData.getMac();
148: AlgorithmIdentifier algId = dInfo.getAlgorithmId();
149: byte[] salt = mData.getSalt();
150: int itCount = mData.getIterationCount().intValue();
151:
152: aIn = new ASN1InputStream(new ByteArrayInputStream(
153: ((ASN1OctetString) info.getContent()).getOctets()));
154:
155: AuthenticatedSafe authSafe = new AuthenticatedSafe(
156: (ASN1Sequence) aIn.readObject());
157: ContentInfo[] c = authSafe.getContentInfo();
158:
159: //
160: // private key section
161: //
162: if (!c[0].getContentType().equals(
163: PKCSObjectIdentifiers.data)) {
164: return new SimpleTestResult(false, getName()
165: + ": failed comparison data test");
166: }
167:
168: aIn = new ASN1InputStream(new ByteArrayInputStream(
169: ((ASN1OctetString) c[0].getContent()).getOctets()));
170: ASN1Sequence seq = (ASN1Sequence) aIn.readObject();
171:
172: SafeBag b = new SafeBag((ASN1Sequence) seq.getObjectAt(0));
173: if (!b.getBagId().equals(
174: PKCSObjectIdentifiers.pkcs8ShroudedKeyBag)) {
175: return new SimpleTestResult(false, getName()
176: + ": failed comparison shroudedKeyBag test");
177: }
178:
179: EncryptedPrivateKeyInfo encInfo = EncryptedPrivateKeyInfo
180: .getInstance(b.getBagValue());
181:
182: encInfo = new EncryptedPrivateKeyInfo(encInfo
183: .getEncryptionAlgorithm(), encInfo
184: .getEncryptedData());
185:
186: b = new SafeBag(PKCSObjectIdentifiers.pkcs8ShroudedKeyBag,
187: encInfo.toASN1Object(), b.getBagAttributes());
188:
189: ByteArrayOutputStream abOut = new ByteArrayOutputStream();
190: ASN1OutputStream berOut = new ASN1OutputStream(abOut);
191:
192: berOut.writeObject(new DERSequence(b));
193:
194: c[0] = new ContentInfo(PKCSObjectIdentifiers.data,
195: new BERConstructedOctetString(abOut.toByteArray()));
196:
197: //
198: // certificates
199: //
200: if (!c[1].getContentType().equals(
201: PKCSObjectIdentifiers.encryptedData)) {
202: return new SimpleTestResult(false, getName()
203: + ": failed comparison encryptedData test");
204: }
205:
206: EncryptedData eData = EncryptedData.getInstance(c[1]
207: .getContent());
208:
209: c[1] = new ContentInfo(PKCSObjectIdentifiers.encryptedData,
210: eData);
211:
212: //
213: // create an octet stream represent the BER encoding of authSafe
214: //
215: authSafe = new AuthenticatedSafe(c);
216:
217: abOut = new ByteArrayOutputStream();
218: berOut = new ASN1OutputStream(abOut);
219:
220: berOut.writeObject(authSafe);
221:
222: info = new ContentInfo(PKCSObjectIdentifiers.data,
223: new BERConstructedOctetString(abOut.toByteArray()));
224:
225: mData = new MacData(
226: new DigestInfo(algId, dInfo.getDigest()), salt,
227: itCount);
228:
229: bag = new Pfx(info, mData);
230:
231: //
232: // comparison test
233: //
234:
235: ByteArrayOutputStream bOut = new ByteArrayOutputStream();
236: ASN1OutputStream aOut = new ASN1OutputStream(bOut);
237:
238: aOut.writeObject(bag);
239:
240: if (!isSameAs(bOut.toByteArray(), pkcs12)) {
241: return new SimpleTestResult(false, getName()
242: + ": failed comparison test");
243: }
244:
245: return new SimpleTestResult(true, getName() + ": Okay");
246: } catch (Exception e) {
247: return new SimpleTestResult(false, getName()
248: + ": exception - " + e.toString(), e);
249: }
250: }
251:
252: public String getName() {
253: return "PKCS12";
254: }
255:
256: public static void main(String[] args) {
257: PKCS12Test test = new PKCS12Test();
258: TestResult result = test.perform();
259:
260: System.out.println(result);
261: }
262: }
|