KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > se > anatom > ejbca > protocol > cmp > CmpTestCase


1 /*************************************************************************
2  * *
3  * EJBCA: The OpenSource Certificate Authority *
4  * *
5  * This software is free software; you can redistribute it and/or *
6  * modify it under the terms of the GNU Lesser General Public *
7  * License as published by the Free Software Foundation; either *
8  * version 2.1 of the License, or any later version. *
9  * *
10  * See terms of license at gnu.org. *
11  * *
12  *************************************************************************/

13
14 package se.anatom.ejbca.protocol.cmp;
15
16 import java.io.BufferedOutputStream JavaDoc;
17 import java.io.ByteArrayInputStream JavaDoc;
18 import java.io.ByteArrayOutputStream JavaDoc;
19 import java.io.DataInputStream JavaDoc;
20 import java.io.DataOutputStream JavaDoc;
21 import java.io.IOException JavaDoc;
22 import java.io.InputStream JavaDoc;
23 import java.io.OutputStream JavaDoc;
24 import java.math.BigInteger JavaDoc;
25 import java.net.HttpURLConnection JavaDoc;
26 import java.net.Socket JavaDoc;
27 import java.net.URL JavaDoc;
28 import java.security.InvalidKeyException JavaDoc;
29 import java.security.KeyPair JavaDoc;
30 import java.security.MessageDigest JavaDoc;
31 import java.security.NoSuchAlgorithmException JavaDoc;
32 import java.security.NoSuchProviderException JavaDoc;
33 import java.security.Signature JavaDoc;
34 import java.security.SignatureException JavaDoc;
35 import java.security.cert.CertificateException JavaDoc;
36 import java.security.cert.X509Certificate JavaDoc;
37 import java.util.Arrays JavaDoc;
38 import java.util.Date JavaDoc;
39 import java.util.Vector JavaDoc;
40
41 import javax.crypto.Mac;
42 import javax.crypto.SecretKey;
43 import javax.crypto.spec.SecretKeySpec;
44
45 import junit.framework.TestCase;
46
47 import org.apache.log4j.Logger;
48 import org.bouncycastle.asn1.ASN1InputStream;
49 import org.bouncycastle.asn1.ASN1Sequence;
50 import org.bouncycastle.asn1.DERBitString;
51 import org.bouncycastle.asn1.DERGeneralizedTime;
52 import org.bouncycastle.asn1.DERInteger;
53 import org.bouncycastle.asn1.DERNull;
54 import org.bouncycastle.asn1.DERObjectIdentifier;
55 import org.bouncycastle.asn1.DEROctetString;
56 import org.bouncycastle.asn1.DEROutputStream;
57 import org.bouncycastle.asn1.DERUTF8String;
58 import org.bouncycastle.asn1.pkcs.PKCSObjectIdentifiers;
59 import org.bouncycastle.asn1.x509.AlgorithmIdentifier;
60 import org.bouncycastle.asn1.x509.GeneralName;
61 import org.bouncycastle.asn1.x509.GeneralNames;
62 import org.bouncycastle.asn1.x509.ReasonFlags;
63 import org.bouncycastle.asn1.x509.SubjectPublicKeyInfo;
64 import org.bouncycastle.asn1.x509.X509CertificateStructure;
65 import org.bouncycastle.asn1.x509.X509Extension;
66 import org.bouncycastle.asn1.x509.X509Extensions;
67 import org.bouncycastle.asn1.x509.X509Name;
68 import org.ejbca.util.CertTools;
69
70 import com.novosec.pkix.asn1.cmp.CMPObjectIdentifiers;
71 import com.novosec.pkix.asn1.cmp.CertConfirmContent;
72 import com.novosec.pkix.asn1.cmp.CertOrEncCert;
73 import com.novosec.pkix.asn1.cmp.CertRepMessage;
74 import com.novosec.pkix.asn1.cmp.CertResponse;
75 import com.novosec.pkix.asn1.cmp.CertifiedKeyPair;
76 import com.novosec.pkix.asn1.cmp.ErrorMsgContent;
77 import com.novosec.pkix.asn1.cmp.PKIBody;
78 import com.novosec.pkix.asn1.cmp.PKIFreeText;
79 import com.novosec.pkix.asn1.cmp.PKIHeader;
80 import com.novosec.pkix.asn1.cmp.PKIMessage;
81 import com.novosec.pkix.asn1.cmp.PKIStatusInfo;
82 import com.novosec.pkix.asn1.cmp.RevDetails;
83 import com.novosec.pkix.asn1.cmp.RevRepContent;
84 import com.novosec.pkix.asn1.cmp.RevReqContent;
85 import com.novosec.pkix.asn1.crmf.AttributeTypeAndValue;
86 import com.novosec.pkix.asn1.crmf.CRMFObjectIdentifiers;
87 import com.novosec.pkix.asn1.crmf.CertReqMessages;
88 import com.novosec.pkix.asn1.crmf.CertReqMsg;
89 import com.novosec.pkix.asn1.crmf.CertRequest;
90 import com.novosec.pkix.asn1.crmf.CertTemplate;
91 import com.novosec.pkix.asn1.crmf.OptionalValidity;
92 import com.novosec.pkix.asn1.crmf.PBMParameter;
93 import com.novosec.pkix.asn1.crmf.POPOSigningKey;
94 import com.novosec.pkix.asn1.crmf.ProofOfPossession;
95
96 /**
97  * Helper class for CMP Junit tests
98  * @author tomas
99  * @version $Id: CmpTestCase.java,v 1.2 2006/11/02 18:05:20 anatom Exp $
100  *
101  */

102 public class CmpTestCase extends TestCase {
103
104     private static Logger log = Logger.getLogger(CmpTestCase.class);
105     
106     private static final String JavaDoc httpReqPath = "http://127.0.0.1:8080/ejbca";
107     private static final String JavaDoc resourceCmp = "publicweb/cmp";
108
109     private static final int PORT_NUMBER = 5547;
110     private static final String JavaDoc CMP_HOST = "127.0.0.1";
111     
112     public CmpTestCase(String JavaDoc arg0) {
113         super(arg0);
114     }
115
116     protected PKIMessage genCertReq(String JavaDoc issuerDN, String JavaDoc userDN, KeyPair JavaDoc keys, X509Certificate JavaDoc cacert, byte[] nonce, byte[] transid, boolean raVerifiedPopo) throws NoSuchAlgorithmException JavaDoc, NoSuchProviderException JavaDoc, IOException JavaDoc, InvalidKeyException JavaDoc, SignatureException JavaDoc {
117         OptionalValidity myOptionalValidity = new OptionalValidity();
118         myOptionalValidity.setNotBefore( new org.bouncycastle.asn1.x509.Time( new DERGeneralizedTime("20030211002120Z") ) );
119         myOptionalValidity.setNotAfter( new org.bouncycastle.asn1.x509.Time(new Date JavaDoc()) );
120         
121         CertTemplate myCertTemplate = new CertTemplate();
122         myCertTemplate.setValidity( myOptionalValidity );
123         myCertTemplate.setIssuer(new X509Name(issuerDN));
124         myCertTemplate.setSubject(new X509Name(userDN));
125         byte[] bytes = keys.getPublic().getEncoded();
126         ByteArrayInputStream JavaDoc bIn = new ByteArrayInputStream JavaDoc(bytes);
127         ASN1InputStream dIn = new ASN1InputStream(bIn);
128         SubjectPublicKeyInfo keyInfo = new SubjectPublicKeyInfo((ASN1Sequence)dIn.readObject());
129         myCertTemplate.setPublicKey(keyInfo);
130         // Some altNames
131
GeneralNames san = CertTools.getGeneralNamesFromAltName("UPN=fooupn@bar.com,rfc822Name=fooemail@bar.com");
132         X509Extensions exts = null;
133         if (san != null) {
134             ByteArrayOutputStream JavaDoc bOut = new ByteArrayOutputStream JavaDoc();
135             DEROutputStream dOut = new DEROutputStream(bOut);
136             dOut.writeObject(san);
137             byte[] value = bOut.toByteArray();
138             X509Extension ext = new X509Extension(false, new DEROctetString(value));
139             Vector JavaDoc values = new Vector JavaDoc();
140             Vector JavaDoc oids = new Vector JavaDoc();
141             values.add(ext);
142             oids.add(X509Extensions.SubjectAlternativeName);
143             exts = new X509Extensions(oids, values);
144         }
145         myCertTemplate.setExtensions(exts);
146         
147         CertRequest myCertRequest = new CertRequest(new DERInteger(4), myCertTemplate);
148         //myCertRequest.addControls(new AttributeTypeAndValue(CRMFObjectIdentifiers.regInfo_utf8Pairs, new DERInteger(12345)));
149
CertReqMsg myCertReqMsg = new CertReqMsg(myCertRequest);
150         
151         // POPO
152
/*
153         PKMACValue myPKMACValue =
154             new PKMACValue(
155                     new AlgorithmIdentifier(new DERObjectIdentifier("8.2.1.2.3.4"), new DERBitString(new byte[] { 8, 1, 1, 2 })),
156                     new DERBitString(new byte[] { 12, 29, 37, 43 }));
157         
158         POPOPrivKey myPOPOPrivKey = new POPOPrivKey(new DERBitString(new byte[] { 44 }), 2); //take choice pos tag 2
159         
160         POPOSigningKeyInput myPOPOSigningKeyInput =
161             new POPOSigningKeyInput(
162                     myPKMACValue,
163                     new SubjectPublicKeyInfo(
164                             new AlgorithmIdentifier(new DERObjectIdentifier("9.3.3.9.2.2"), new DERBitString(new byte[] { 2, 9, 7, 3 })),
165                             new byte[] { 7, 7, 7, 4, 5, 6, 7, 7, 7 }));
166         */

167         ProofOfPossession myProofOfPossession = null;
168         if (raVerifiedPopo) {
169             // raVerified POPO (meaning there is no POPO)
170
myProofOfPossession = new ProofOfPossession(new DERNull(), 0);
171         } else {
172             ByteArrayOutputStream JavaDoc baos = new ByteArrayOutputStream JavaDoc();
173             DEROutputStream mout = new DEROutputStream( baos );
174             mout.writeObject( myCertRequest );
175             mout.close();
176             byte[] popoProtectionBytes = baos.toByteArray();
177             Signature JavaDoc sig = Signature.getInstance( PKCSObjectIdentifiers.sha1WithRSAEncryption.getId(), "BC");
178             sig.initSign(keys.getPrivate());
179             sig.update( popoProtectionBytes );
180             
181             DERBitString bs = new DERBitString(sig.sign());
182
183             POPOSigningKey myPOPOSigningKey =
184                 new POPOSigningKey(
185                         new AlgorithmIdentifier(PKCSObjectIdentifiers.sha1WithRSAEncryption),
186                         bs);
187             //myPOPOSigningKey.setPoposkInput( myPOPOSigningKeyInput );
188
myProofOfPossession = new ProofOfPossession(myPOPOSigningKey, 1);
189         }
190                 
191         myCertReqMsg.setPop(myProofOfPossession);
192         //myCertReqMsg.addRegInfo(new AttributeTypeAndValue(new DERObjectIdentifier("1.3.6.2.2.2.2.3.1"), new DERInteger(1122334455)));
193
AttributeTypeAndValue av = new AttributeTypeAndValue(CRMFObjectIdentifiers.regCtrl_regToken, new DERUTF8String("foo123"));
194         myCertReqMsg.addRegInfo(av);
195         
196         CertReqMessages myCertReqMessages = new CertReqMessages(myCertReqMsg);
197         //myCertReqMessages.addCertReqMsg(myCertReqMsg);
198

199         PKIHeader myPKIHeader =
200             new PKIHeader(
201                     new DERInteger(2),
202                     new GeneralName(new X509Name(userDN)),
203                     new GeneralName(new X509Name(cacert.getSubjectDN().getName())));
204         myPKIHeader.setMessageTime(new DERGeneralizedTime(new Date JavaDoc()));
205         // senderNonce
206
myPKIHeader.setSenderNonce(new DEROctetString(nonce));
207         // TransactionId
208
myPKIHeader.setTransactionID(new DEROctetString(transid));
209         //myPKIHeader.setRecipNonce(new DEROctetString(new String("RecipNonce").getBytes()));
210
//PKIFreeText myPKIFreeText = new PKIFreeText(new DERUTF8String("hello"));
211
//myPKIFreeText.addString(new DERUTF8String("free text string"));
212
//myPKIHeader.setFreeText(myPKIFreeText);
213

214         PKIBody myPKIBody = new PKIBody(myCertReqMessages, 0); // initialization request
215
PKIMessage myPKIMessage = new PKIMessage(myPKIHeader, myPKIBody);
216         return myPKIMessage;
217     }
218
219     protected PKIMessage genRevReq(String JavaDoc issuerDN, String JavaDoc userDN, BigInteger JavaDoc serNo, X509Certificate JavaDoc cacert, byte[] nonce, byte[] transid) throws NoSuchAlgorithmException JavaDoc, NoSuchProviderException JavaDoc, IOException JavaDoc, InvalidKeyException JavaDoc, SignatureException JavaDoc {
220         CertTemplate myCertTemplate = new CertTemplate();
221         myCertTemplate.setIssuer(new X509Name(issuerDN));
222         myCertTemplate.setSubject(new X509Name(userDN));
223         myCertTemplate.setSerialNumber(new DERInteger(serNo));
224
225         RevDetails myRevDetails = new RevDetails(myCertTemplate);
226         ReasonFlags reasonbits = new ReasonFlags(ReasonFlags.keyCompromise);
227         myRevDetails.setRevocationReason(reasonbits);
228         
229         RevReqContent myRevReqContent = new RevReqContent(myRevDetails);
230                 
231         PKIHeader myPKIHeader =
232             new PKIHeader(
233                     new DERInteger(2),
234                     new GeneralName(new X509Name(userDN)),
235                     new GeneralName(new X509Name(cacert.getSubjectDN().getName())));
236         myPKIHeader.setMessageTime(new DERGeneralizedTime(new Date JavaDoc()));
237         // senderNonce
238
myPKIHeader.setSenderNonce(new DEROctetString(nonce));
239         // TransactionId
240
myPKIHeader.setTransactionID(new DEROctetString(transid));
241         
242         PKIBody myPKIBody = new PKIBody(myRevReqContent, 11); // revocation request
243
PKIMessage myPKIMessage = new PKIMessage(myPKIHeader, myPKIBody);
244         return myPKIMessage;
245     }
246
247     protected PKIMessage genCertConfirm(String JavaDoc userDN, X509Certificate JavaDoc cacert, byte[] nonce, byte[] transid, String JavaDoc hash, int certReqId) throws NoSuchAlgorithmException JavaDoc, NoSuchProviderException JavaDoc, IOException JavaDoc {
248         
249         PKIHeader myPKIHeader =
250             new PKIHeader(
251                     new DERInteger(2),
252                     new GeneralName(new X509Name(userDN)),
253                     new GeneralName(new X509Name(cacert.getSubjectDN().getName())));
254         myPKIHeader.setMessageTime(new DERGeneralizedTime(new Date JavaDoc()));
255         // senderNonce
256
myPKIHeader.setSenderNonce(new DEROctetString(nonce));
257         // TransactionId
258
myPKIHeader.setTransactionID(new DEROctetString(transid));
259         
260         CertConfirmContent cc = new CertConfirmContent(new DEROctetString(hash.getBytes()), new DERInteger(certReqId));
261         PKIBody myPKIBody = new PKIBody(cc, 24); // Cert Confirm
262
PKIMessage myPKIMessage = new PKIMessage(myPKIHeader, myPKIBody);
263         return myPKIMessage;
264     }
265
266     protected PKIMessage protectPKIMessage(PKIMessage msg, boolean badObjectId, String JavaDoc password) throws NoSuchAlgorithmException JavaDoc, NoSuchProviderException JavaDoc, InvalidKeyException JavaDoc {
267         // Create the PasswordBased protection of the message
268
PKIHeader head = msg.getHeader();
269         head.setSenderKID(new DEROctetString("primekey".getBytes()));
270         // SHA1
271
AlgorithmIdentifier owfAlg = new AlgorithmIdentifier("1.3.14.3.2.26");
272         // 567 iterations
273
int iterationCount = 567;
274         DERInteger iteration = new DERInteger(iterationCount);
275         // HMAC/SHA1
276
AlgorithmIdentifier macAlg = new AlgorithmIdentifier("1.2.840.113549.2.7");
277         byte[] salt = "foo123".getBytes();
278         DEROctetString derSalt = new DEROctetString(salt);
279         
280         // Create the new protected return message
281
String JavaDoc objectId = "1.2.840.113533.7.66.13";
282         if (badObjectId) {
283             objectId += ".7";
284         }
285         PBMParameter pp = new PBMParameter(derSalt, owfAlg, iteration, macAlg);
286         AlgorithmIdentifier pAlg = new AlgorithmIdentifier(new DERObjectIdentifier(objectId), pp);
287         head.setProtectionAlg(pAlg);
288         PKIBody body = msg.getBody();
289         PKIMessage ret = new PKIMessage(head, body);
290
291         // Calculate the protection bits
292
byte[] raSecret = password.getBytes();
293         byte[] basekey = new byte[raSecret.length + salt.length];
294         for (int i = 0; i < raSecret.length; i++) {
295             basekey[i] = raSecret[i];
296         }
297         for (int i = 0; i < salt.length; i++) {
298             basekey[raSecret.length+i] = salt[i];
299         }
300         // Construct the base key according to rfc4210, section 5.1.3.1
301
MessageDigest JavaDoc dig = MessageDigest.getInstance(owfAlg.getObjectId().getId(), "BC");
302         for (int i = 0; i < iterationCount; i++) {
303             basekey = dig.digest(basekey);
304             dig.reset();
305         }
306         // For HMAC/SHA1 there is another oid, that is not known in BC, but the result is the same so...
307
String JavaDoc macOid = macAlg.getObjectId().getId();
308         byte[] protectedBytes = ret.getProtectedBytes();
309         Mac mac = Mac.getInstance(macOid, "BC");
310         SecretKey key = new SecretKeySpec(basekey, macOid);
311         mac.init(key);
312         mac.reset();
313         mac.update(protectedBytes, 0, protectedBytes.length);
314         byte[] out = mac.doFinal();
315         DERBitString bs = new DERBitString(out);
316
317         // Finally store the protection bytes in the msg
318
ret.setProtection(bs);
319         return ret;
320     }
321
322     protected byte[] sendCmpHttp(byte[] message) throws IOException JavaDoc, NoSuchProviderException JavaDoc {
323         // POST the CMP request
324
// we are going to do a POST
325
String JavaDoc resource = resourceCmp;
326         String JavaDoc urlString = httpReqPath + '/' + resource;
327         HttpURLConnection JavaDoc con = null;
328         URL JavaDoc url = new URL JavaDoc(urlString);
329         con = (HttpURLConnection JavaDoc)url.openConnection();
330         con.setDoOutput(true);
331         con.setRequestMethod("POST");
332         con.setRequestProperty("Content-type", "application/pkixcmp");
333         con.connect();
334         // POST it
335
OutputStream JavaDoc os = con.getOutputStream();
336         os.write(message);
337         os.close();
338
339         assertEquals(con.getResponseCode(), 200);
340         assertEquals("application/pkixcmp", con.getContentType());
341         ByteArrayOutputStream JavaDoc baos = new ByteArrayOutputStream JavaDoc();
342         // This works for small requests, and CMP requests are small enough
343
InputStream JavaDoc in = con.getInputStream();
344         int b = in.read();
345         while (b != -1) {
346             baos.write(b);
347             b = in.read();
348         }
349         baos.flush();
350         in.close();
351         byte[] respBytes = baos.toByteArray();
352         assertNotNull(respBytes);
353         assertTrue(respBytes.length > 0);
354         return respBytes;
355     }
356
357     
358     protected void checkCmpResponseGeneral(byte[] retMsg, String JavaDoc issuerDN, String JavaDoc userDN, X509Certificate JavaDoc cacert, byte[] senderNonce, byte[] transId, boolean signed, boolean pbe) throws Exception JavaDoc {
359         //
360
// Parse response message
361
//
362
PKIMessage respObject = PKIMessage.getInstance(new ASN1InputStream(new ByteArrayInputStream JavaDoc(retMsg)).readObject());
363         assertNotNull(respObject);
364         
365         // The signer, i.e. the CA, check it's the right CA
366
PKIHeader header = respObject.getHeader();
367
368         // Check that the message is signed with the correct digest alg
369
if (signed) {
370             AlgorithmIdentifier algId = header.getProtectionAlg();
371             assertNotNull(algId);
372             assertEquals(algId.getObjectId().getId(), PKCSObjectIdentifiers.sha1WithRSAEncryption.getId());
373         }
374         if (pbe) {
375             AlgorithmIdentifier algId = header.getProtectionAlg();
376             assertNotNull(algId);
377             assertEquals(algId.getObjectId().getId(), CMPObjectIdentifiers.passwordBasedMac.getId());
378         }
379
380         // Check that the signer is the expected CA
381
assertEquals(header.getSender().getTagNo(), 4);
382         X509Name name = X509Name.getInstance(header.getSender().getName());
383         assertEquals(name.toString(), issuerDN);
384
385         if (signed) {
386             // Verify the signature
387
byte[] protBytes = respObject.getProtectedBytes();
388             DERBitString bs = respObject.getProtection();
389             Signature JavaDoc sig;
390             try {
391                 sig = Signature.getInstance(PKCSObjectIdentifiers.sha1WithRSAEncryption.getId(), "BC");
392                 sig.initVerify(cacert);
393                 sig.update(protBytes);
394                 boolean ret = sig.verify(bs.getBytes());
395                 assertTrue(ret);
396             } catch (NoSuchAlgorithmException JavaDoc e) {
397                 e.printStackTrace();
398                 assertTrue(false);
399             } catch (NoSuchProviderException JavaDoc e) {
400                 e.printStackTrace();
401                 assertTrue(false);
402             } catch (InvalidKeyException JavaDoc e) {
403                 e.printStackTrace();
404                 assertTrue(false);
405             } catch (SignatureException JavaDoc e) {
406                 e.printStackTrace();
407                 assertTrue(false);
408             }
409         }
410         if (pbe) {
411             DEROctetString os = header.getSenderKID();
412             assertNotNull(os);
413                 String JavaDoc keyId = new String JavaDoc(os.getOctets());
414                 log.debug("Found a sender keyId: "+keyId);
415                 // Verify the PasswordBased protection of the message
416
byte[] protectedBytes = respObject.getProtectedBytes();
417                 DERBitString protection = respObject.getProtection();
418                 AlgorithmIdentifier pAlg = header.getProtectionAlg();
419                 log.debug("Protection type is: "+pAlg.getObjectId().getId());
420                 PBMParameter pp = PBMParameter.getInstance(pAlg.getParameters());
421                 int iterationCount = pp.getIterationCount().getPositiveValue().intValue();
422                 log.debug("Iteration count is: "+iterationCount);
423                 AlgorithmIdentifier owfAlg = pp.getOwf();
424                 // Normal OWF alg is 1.3.14.3.2.26 - SHA1
425
log.debug("Owf type is: "+owfAlg.getObjectId().getId());
426                 AlgorithmIdentifier macAlg = pp.getMac();
427                 // Normal mac alg is 1.3.6.1.5.5.8.1.2 - HMAC/SHA1
428
log.debug("Mac type is: "+macAlg.getObjectId().getId());
429                 byte[] salt = pp.getSalt().getOctets();
430                 //log.info("Salt is: "+new String(salt));
431
String JavaDoc raAuthenticationSecret = "password";
432                 byte[] raSecret = raAuthenticationSecret.getBytes();
433                 byte[] basekey = new byte[raSecret.length + salt.length];
434                 for (int i = 0; i < raSecret.length; i++) {
435                     basekey[i] = raSecret[i];
436                 }
437                 for (int i = 0; i < salt.length; i++) {
438                     basekey[raSecret.length+i] = salt[i];
439                 }
440                 // Construct the base key according to rfc4210, section 5.1.3.1
441
MessageDigest JavaDoc dig = MessageDigest.getInstance(owfAlg.getObjectId().getId(), "BC");
442                 for (int i = 0; i < iterationCount; i++) {
443                     basekey = dig.digest(basekey);
444                     dig.reset();
445                 }
446                 // HMAC/SHA1 os normal 1.3.6.1.5.5.8.1.2 or 1.2.840.113549.2.7
447
String JavaDoc macOid = macAlg.getObjectId().getId();
448                 Mac mac = Mac.getInstance(macOid, "BC");
449                 SecretKey key = new SecretKeySpec(basekey, macOid);
450                 mac.init(key);
451                 mac.reset();
452                 mac.update(protectedBytes, 0, protectedBytes.length);
453                 byte[] out = mac.doFinal();
454                 // My out should now be the same as the protection bits
455
byte[] pb = protection.getBytes();
456                 boolean ret = Arrays.equals(out, pb);
457                 assertTrue(ret);
458         }
459
460         // --SenderNonce
461
// SenderNonce is something the server came up with, but it should be 16 chars
462
byte[] nonce = header.getSenderNonce().getOctets();
463         assertEquals(nonce.length, 16);
464
465         // --Recipient Nonce
466
// recipient nonce should be the same as we sent away as sender nonce
467
nonce = header.getRecipNonce().getOctets();
468         assertEquals(new String JavaDoc(nonce), new String JavaDoc(senderNonce));
469
470         // --Transaction ID
471
// transid should be the same as the one we sent
472
nonce = header.getTransactionID().getOctets();
473         assertEquals(new String JavaDoc(nonce), new String JavaDoc(transId));
474                 
475     }
476     
477     /**
478      *
479      * @param message
480      * @param type set to 5 when sending a PKI request, 3 when sending a PKIConf
481      * @return
482      * @throws IOException
483      * @throws NoSuchProviderException
484      */

485     protected byte[] sendCmpTcp(byte[] message, int type) throws IOException JavaDoc, NoSuchProviderException JavaDoc {
486         byte[] respBytes = null;
487         try {
488             int port = PORT_NUMBER;
489             String JavaDoc host = CMP_HOST;
490             Socket JavaDoc socket = new Socket JavaDoc(host, port);
491
492             byte[] msg = createTcpMessage(message);
493
494             BufferedOutputStream JavaDoc os = new BufferedOutputStream JavaDoc(socket.getOutputStream());
495             os.write(msg);
496             os.flush();
497
498             DataInputStream JavaDoc dis = new DataInputStream JavaDoc(socket.getInputStream());
499             // Read the length, 32 bits
500
int len = dis.readInt();
501             System.out.println("Got a message claiming to be of length: " + len);
502             // Read the version, 8 bits. Version should be 10 (protocol draft nr 5)
503
int ver = dis.readByte();
504             System.out.println("Got a message with version: " + ver);
505             assertEquals(ver, 10);
506             
507             // Read flags, 8 bits for version 10
508
byte flags = dis.readByte();
509             System.out.println("Got a message with flags (1 means close): " + flags);
510             // Check if the client wants us to close the connection (LSB is 1 in that case according to spec)
511

512             // Read message type, 8 bits
513
int msgType = dis.readByte();
514             System.out.println("Got a message of type: " +msgType);
515             assertEquals(msgType, type);
516             
517             // Read message
518
ByteArrayOutputStream JavaDoc baos = new ByteArrayOutputStream JavaDoc(3072);
519             while (dis.available() > 0) {
520                 baos.write(dis.read());
521             }
522             System.out.println("Read "+baos.size()+" bytes");
523             respBytes = baos.toByteArray();
524         } catch(Exception JavaDoc e) {
525             e.printStackTrace();
526             assertTrue(false);
527         }
528         assertNotNull(respBytes);
529         assertTrue(respBytes.length > 0);
530         return respBytes;
531     }
532
533     protected X509Certificate JavaDoc checkCmpCertRepMessage(String JavaDoc userDN, X509Certificate JavaDoc cacert, byte[] retMsg, int requestId) throws IOException JavaDoc, CertificateException JavaDoc {
534         //
535
// Parse response message
536
//
537
PKIMessage respObject = PKIMessage.getInstance(new ASN1InputStream(new ByteArrayInputStream JavaDoc(retMsg)).readObject());
538         assertNotNull(respObject);
539         
540         PKIBody body = respObject.getBody();
541         int tag = body.getTagNo();
542         assertEquals(tag, 1);
543         CertRepMessage c = body.getIp();
544         assertNotNull(c);
545         CertResponse resp = c.getResponse(0);
546         assertNotNull(resp);
547         assertEquals(resp.getCertReqId().getValue().intValue(), requestId);
548         PKIStatusInfo info = resp.getStatus();
549         assertNotNull(info);
550         assertEquals(0, info.getStatus().getValue().intValue());
551         CertifiedKeyPair kp = resp.getCertifiedKeyPair();
552         assertNotNull(kp);
553         CertOrEncCert cc = kp.getCertOrEncCert();
554         assertNotNull(cc);
555         X509CertificateStructure struct = cc.getCertificate();
556         assertNotNull(struct);
557         assertEquals(CertTools.stringToBCDNString(struct.getSubject().toString()), CertTools.stringToBCDNString(userDN));
558         assertEquals(CertTools.stringToBCDNString(struct.getIssuer().toString()), CertTools.stringToBCDNString(cacert.getSubjectDN().getName()));
559         return CertTools.getCertfromByteArray(struct.getEncoded());
560     }
561
562     protected void checkCmpPKIConfirmMessage(String JavaDoc userDN, X509Certificate JavaDoc cacert, byte[] retMsg) throws IOException JavaDoc {
563         //
564
// Parse response message
565
//
566
PKIMessage respObject = PKIMessage.getInstance(new ASN1InputStream(new ByteArrayInputStream JavaDoc(retMsg)).readObject());
567         assertNotNull(respObject);
568         PKIHeader header = respObject.getHeader();
569         assertEquals(header.getSender().getTagNo(), 4);
570         X509Name name = X509Name.getInstance(header.getSender().getName());
571         assertEquals(name.toString(), cacert.getSubjectDN().getName());
572         name = X509Name.getInstance(header.getRecipient().getName());
573         assertEquals(name.toString(), userDN);
574
575         PKIBody body = respObject.getBody();
576         int tag = body.getTagNo();
577         assertEquals(tag, 19);
578         DERNull n = body.getConf();
579         assertNotNull(n);
580     }
581
582     protected void checkCmpRevokeConfirmMessage(String JavaDoc issuerDN, String JavaDoc userDN, BigInteger JavaDoc serno, X509Certificate JavaDoc cacert, byte[] retMsg, boolean success) throws IOException JavaDoc {
583         //
584
// Parse response message
585
//
586
PKIMessage respObject = PKIMessage.getInstance(new ASN1InputStream(new ByteArrayInputStream JavaDoc(retMsg)).readObject());
587         assertNotNull(respObject);
588         PKIHeader header = respObject.getHeader();
589         assertEquals(header.getSender().getTagNo(), 4);
590         X509Name name = X509Name.getInstance(header.getSender().getName());
591         assertEquals(name.toString(), cacert.getSubjectDN().getName());
592         name = X509Name.getInstance(header.getRecipient().getName());
593         assertEquals(name.toString(), userDN);
594
595         PKIBody body = respObject.getBody();
596         int tag = body.getTagNo();
597         assertEquals(tag, 12);
598         RevRepContent n = body.getRp();
599         assertNotNull(n);
600         PKIStatusInfo info = n.getPKIStatusInfo(0);
601         if (success) {
602             assertEquals(info.getStatus().getValue().intValue(), 0);
603         } else {
604             assertEquals(info.getStatus().getValue().intValue(), 2);
605         }
606         
607     }
608     
609     /**
610      *
611      * @param retMsg
612      * @param failMsg
613      * @param tag 1 is answer to initicalization resp, 3 certification resp etc,
614      * @param err a number from FailInfo
615      * @throws IOException
616      */

617     protected void checkCmpFailMessage(byte[] retMsg, String JavaDoc failMsg, int exptag, int requestId, int err) throws IOException JavaDoc {
618         //
619
// Parse response message
620
//
621
PKIMessage respObject = PKIMessage.getInstance(new ASN1InputStream(new ByteArrayInputStream JavaDoc(retMsg)).readObject());
622         assertNotNull(respObject);
623         
624         PKIBody body = respObject.getBody();
625         int tag = body.getTagNo();
626         assertEquals(tag, exptag);
627         if (exptag == 23) {
628             ErrorMsgContent c = body.getError();
629             assertNotNull(c);
630             PKIStatusInfo info = c.getPKIStatus();
631             assertNotNull(info);
632             assertEquals(2, info.getStatus().getValue().intValue());
633             int i = info.getFailInfo().intValue();
634             assertEquals(i,1<<err); // bit nr 7 (INCORRECT_DATA) set is 128
635
assertEquals(failMsg, info.getStatusString().getString(0).getString());
636         } else {
637             CertRepMessage c = null;
638             if (exptag == 1) {
639                 c = body.getIp();
640             } else if (exptag == 3) {
641                 c = body.getCp();
642             }
643             assertNotNull(c);
644             CertResponse resp = c.getResponse(0);
645             assertNotNull(resp);
646             assertEquals(resp.getCertReqId().getValue().intValue(), requestId);
647             PKIStatusInfo info = resp.getStatus();
648             assertNotNull(info);
649             assertEquals(2, info.getStatus().getValue().intValue());
650             int i = info.getFailInfo().intValue();
651             assertEquals(i,1<<7); // bit nr 7 (INCORRECT_DATA) set is 128
652
assertEquals(failMsg, info.getStatusString().getString(0).getString());
653         }
654     }
655     
656     protected void checkCmpPKIErrorMessage(byte[] retMsg, String JavaDoc sender, String JavaDoc recipient, int errorCode, String JavaDoc errorMsg) throws IOException JavaDoc {
657         //
658
// Parse response message
659
//
660
PKIMessage respObject = PKIMessage.getInstance(new ASN1InputStream(new ByteArrayInputStream JavaDoc(retMsg)).readObject());
661         assertNotNull(respObject);
662         PKIHeader header = respObject.getHeader();
663         assertEquals(header.getSender().getTagNo(), 4);
664         X509Name name = X509Name.getInstance(header.getSender().getName());
665         assertEquals(name.toString(), sender);
666         name = X509Name.getInstance(header.getRecipient().getName());
667         assertEquals(name.toString(), recipient);
668
669         PKIBody body = respObject.getBody();
670         int tag = body.getTagNo();
671         assertEquals(tag, 23);
672         ErrorMsgContent n = body.getError();
673         assertNotNull(n);
674         PKIStatusInfo info = n.getPKIStatus();
675         assertNotNull(info);
676         DERInteger i = info.getStatus();
677         assertEquals(i.getValue().intValue(), 2);
678         DERBitString b = info.getFailInfo();
679         assertEquals(errorCode, b.intValue());
680         if (errorMsg != null) {
681             PKIFreeText freeText = info.getStatusString();
682             DERUTF8String utf = freeText.getString(0);
683             assertEquals(errorMsg, utf.getString());
684         }
685     }
686
687     //
688
// Private methods
689
//
690

691     private static byte[] createTcpMessage(byte[] msg) throws IOException JavaDoc {
692         ByteArrayOutputStream JavaDoc bao = new ByteArrayOutputStream JavaDoc();
693         DataOutputStream JavaDoc dos = new DataOutputStream JavaDoc(bao);
694         // 0 is pkiReq
695
int msgType = 0;
696         int len = msg.length;
697         // return msg length = msg.length + 3; 1 byte version, 1 byte flags and 1 byte message type
698
dos.writeInt(len+3);
699         dos.writeByte(10);
700         dos.writeByte(0); // 1 if we should close, 0 otherwise
701
dos.writeByte(msgType);
702         dos.write(msg);
703         dos.flush();
704         return bao.toByteArray();
705     }
706     
707
708
709 }
710
Popular Tags