001: /*
002: * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
003: *
004: * Copyright 1997-2007 Sun Microsystems, Inc. All rights reserved.
005: *
006: * The contents of this file are subject to the terms of either the GNU
007: * General Public License Version 2 only ("GPL") or the Common Development
008: * and Distribution License("CDDL") (collectively, the "License"). You
009: * may not use this file except in compliance with the License. You can obtain
010: * a copy of the License at https://glassfish.dev.java.net/public/CDDL+GPL.html
011: * or glassfish/bootstrap/legal/LICENSE.txt. See the License for the specific
012: * language governing permissions and limitations under the License.
013: *
014: * When distributing the software, include this License Header Notice in each
015: * file and include the License file at glassfish/bootstrap/legal/LICENSE.txt.
016: * Sun designates this particular file as subject to the "Classpath" exception
017: * as provided by Sun in the GPL Version 2 section of the License file that
018: * accompanied this code. If applicable, add the following below the License
019: * Header, with the fields enclosed by brackets [] replaced by your own
020: * identifying information: "Portions Copyrighted [year]
021: * [name of copyright owner]"
022: *
023: * Contributor(s):
024: *
025: * If you wish your version of this file to be governed by only the CDDL or
026: * only the GPL Version 2, indicate your decision by adding "[Contributor]
027: * elects to include this software in this distribution under the [CDDL or GPL
028: * Version 2] license." If you don't indicate a single choice of license, a
029: * recipient has the option to distribute your version of this file under
030: * either the CDDL, the GPL Version 2 or to extend the choice of license to
031: * its licensees as provided above. However, if you add GPL Version 2 code
032: * and therefore, elected the GPL Version 2 license, then the option applies
033: * only if the new code is made subject to such option by the copyright
034: * holder.
035: */
036: package com.sun.xml.wss.impl;
037:
038: import java.util.*;
039: import java.io.*;
040:
041: import com.sun.xml.wss.callback.PolicyCallbackHandler1;
042: import com.sun.xml.wss.*;
043:
044: import javax.xml.soap.*;
045: import com.sun.xml.wss.impl.policy.mls.*;
046: import com.sun.xml.wss.ProcessingContext;
047: import com.sun.xml.ws.security.impl.*;
048: import com.sun.xml.wss.core.*;
049: import com.sun.xml.wss.impl.ProcessingContextImpl;
050: import com.sun.xml.ws.security.impl.policy.*;
051: import javax.xml.namespace.QName;
052: import java.security.SecureRandom;
053: import com.sun.xml.wss.impl.misc.*;
054: import javax.security.auth.callback.CallbackHandler;
055: import com.sun.xml.wss.impl.*;
056: import javax.xml.crypto.dsig.DigestMethod;
057: import com.sun.xml.ws.security.policy.AlgorithmSuiteValue;
058: import com.sun.xml.wss.impl.AlgorithmSuite;
059: import junit.framework.Test;
060: import junit.framework.TestCase;
061: import junit.framework.TestSuite;
062:
063: import com.sun.xml.wss.core.reference.*;
064:
065: import java.math.BigInteger;
066:
067: import java.text.SimpleDateFormat;
068:
069: import java.security.KeyStore;
070: import java.security.PrivateKey;
071: import java.security.PublicKey;
072: import java.security.cert.X509Certificate;
073:
074: import javax.xml.bind.JAXBContext;
075: import javax.xml.bind.JAXBException;
076:
077: import java.security.cert.CertPathBuilder;
078: import java.security.cert.Certificate;
079: import java.security.cert.CertificateExpiredException;
080: import java.security.cert.CertificateNotYetValidException;
081: import java.security.cert.PKIXBuilderParameters;
082: import java.security.cert.PKIXCertPathBuilderResult;
083: import java.security.cert.X509CertSelector;
084:
085: import javax.security.auth.callback.Callback;
086: import javax.security.auth.callback.CallbackHandler;
087: import javax.security.auth.callback.UnsupportedCallbackException;
088:
089: import com.sun.xml.wss.impl.policy.mls.PrivateKeyBinding;
090: import com.sun.xml.wss.impl.policy.mls.SymmetricKeyBinding;
091: import com.sun.xml.wss.impl.policy.mls.AuthenticationTokenPolicy;
092:
093: import com.sun.xml.wss.impl.configuration.StaticApplicationContext;
094: import com.sun.xml.wss.impl.configuration.DynamicApplicationContext;
095:
096: import com.sun.xml.wss.impl.policy.SecurityPolicy;
097: import com.sun.xml.wss.impl.callback.*;
098:
099: import com.sun.xml.wss.saml.*;
100:
101: import javax.xml.crypto.*;
102: import javax.xml.crypto.dsig.*;
103: import javax.xml.crypto.dom.*;
104: import javax.xml.crypto.dsig.dom.DOMSignContext;
105: import javax.xml.crypto.dsig.keyinfo.*;
106: import javax.xml.crypto.dsig.spec.*;
107:
108: import javax.xml.parsers.DocumentBuilderFactory;
109:
110: import org.w3c.dom.*;
111:
112: import java.security.Provider;
113:
114: import java.security.cert.Certificate;
115: import com.sun.org.apache.xml.internal.security.keys.KeyInfo;
116:
117: import com.sun.xml.wss.saml.util.*;
118: import com.sun.xml.ws.security.trust.*;
119: import com.sun.xml.wss.impl.keyinfo.*;
120:
121: public class TrustDKTTest extends TestCase {
122:
123: public static final String holderOfKeyConfirmation = "urn:oasis:names:tc:SAML:1.0:cm:holder-of-key";
124: public static final String senderVouchesConfirmation = "urn:oasis:names:tc:SAML:1.0:cm:sender-vouches";
125:
126: private static Hashtable<String, IssuedTokenContextImpl> map = new Hashtable<String, IssuedTokenContextImpl>();
127: private static AlgorithmSuite alg = null;
128:
129: public TrustDKTTest(String testName) throws Exception {
130: super (testName);
131: }
132:
133: protected void setUp() throws Exception {
134:
135: }
136:
137: protected void tearDown() throws Exception {
138: }
139:
140: public static Test suite() {
141: TestSuite suite = new TestSuite(TrustDKTTest.class);
142:
143: return suite;
144: }
145:
146: public static void testTrustIntegrationTest() throws Exception {
147:
148: //System.setProperty("com.sun.xml.wss.saml.binding.jaxb", "true");
149: // alg.setType(AlgorithmSuiteValue.Basic128);
150: alg = new AlgorithmSuite(AlgorithmSuiteValue.Basic128
151: .getDigAlgorithm(), AlgorithmSuiteValue.Basic128
152: .getEncAlgorithm(), AlgorithmSuiteValue.Basic128
153: .getSymKWAlgorithm(), AlgorithmSuiteValue.Basic128
154: .getAsymKWAlgorithm());
155: SignaturePolicy signaturePolicy = new SignaturePolicy();
156: SignatureTarget st = new SignatureTarget();
157: st.setType("qname");
158: st.setDigestAlgorithm(DigestMethod.SHA1);
159: SignatureTarget.Transform trans = new SignatureTarget.Transform();
160: trans
161: .setTransform(MessageConstants.TRANSFORM_C14N_EXCL_OMIT_COMMENTS);
162: st.addTransform(trans);
163:
164: ((SignaturePolicy.FeatureBinding) signaturePolicy
165: .getFeatureBinding()).addTargetBinding(st);
166: ((SignaturePolicy.FeatureBinding) signaturePolicy
167: .getFeatureBinding())
168: .setCanonicalizationAlgorithm(MessageConstants.TRANSFORM_C14N_EXCL_OMIT_COMMENTS);
169:
170: IssuedTokenKeyBinding isKB = (IssuedTokenKeyBinding) signaturePolicy
171: .newIssuedTokenKeyBinding();
172:
173: DerivedTokenKeyBinding dktSigKB = (DerivedTokenKeyBinding) signaturePolicy
174: .newDerivedTokenKeyBinding();
175: dktSigKB.setOriginalKeyBinding(isKB);
176:
177: EncryptionPolicy encryptPolicy = new EncryptionPolicy();
178: EncryptionTarget et = new EncryptionTarget();
179: et.setType("qname");
180: ((EncryptionPolicy.FeatureBinding) encryptPolicy
181: .getFeatureBinding()).addTargetBinding(st);
182: ((EncryptionPolicy.FeatureBinding) encryptPolicy
183: .getFeatureBinding())
184: .setDataEncryptionAlgorithm(MessageConstants.AES_BLOCK_ENCRYPTION_128);
185: IssuedTokenKeyBinding ieKB = (IssuedTokenKeyBinding) encryptPolicy
186: .newIssuedTokenKeyBinding();
187:
188: DerivedTokenKeyBinding dktEncKB = (DerivedTokenKeyBinding) encryptPolicy
189: .newDerivedTokenKeyBinding();
190: dktEncKB.setOriginalKeyBinding(ieKB);
191:
192: QName name = new QName("IssuedToken");
193: Token tok = new Token(name);
194: //isKB.setPolicyToken(tok);
195: //ieKB.setPolicyToken(tok);
196: isKB.setUUID(new String("12015"));
197: ieKB.setUUID(new String("12015"));
198: MessagePolicy pol = new MessagePolicy();
199: //pol.dumpMessages(true);
200: signaturePolicy.setUUID("22222");
201: pol.append(encryptPolicy);
202: pol.append(signaturePolicy);
203:
204: SOAPMessage msg = MessageFactory.newInstance().createMessage();
205: SOAPBody body = msg.getSOAPBody();
206: SOAPBodyElement sbe = body.addBodyElement(SOAPFactory
207: .newInstance().createName("StockSymbol", "tru",
208: "http://fabrikam123.com/payloads"));
209: sbe.addTextNode("QQQ");
210:
211: //Create processing context and set the soap
212: //message to be processed.
213: ProcessingContextImpl context = new ProcessingContextImpl();
214: context.setSOAPMessage(msg);
215: context.hasIssuedToken(true);
216: // create a new IssuedTokenContext
217: IssuedTokenContextImpl impl = new IssuedTokenContextImpl();
218:
219: SecureRandom rnd = SecureRandom.getInstance("SHA1PRNG");
220: byte[] keyBytes = new byte[16];
221: rnd.nextBytes(keyBytes);
222: impl.setProofKey(keyBytes);
223:
224: // create a SAML Token and set it here
225: Assertion assertion = createHOKAssertion(keyBytes, msg
226: .getSOAPPart());
227:
228: // Get the client's public and private key to sign SAML Assertion
229:
230: SignatureKeyCallback.DefaultPrivKeyCertRequest request = new SignatureKeyCallback.DefaultPrivKeyCertRequest();
231: Callback skc = new SignatureKeyCallback(request);
232: Callback[] callbacks = { skc };
233: CallbackHandler handler = new PolicyCallbackHandler1("client");
234: handler.handle(callbacks);
235: PrivateKey stsPrivKey = request.getPrivateKey();
236:
237: // Sign the assertion with Client's private key
238: Element signedSamlElem = assertion.sign(request
239: .getX509Certificate(), stsPrivKey);
240:
241: impl.setSecurityToken(new GenericToken(signedSamlElem));
242:
243: SecurityTokenReference str = new SecurityTokenReference(msg
244: .getSOAPPart());
245: KeyIdentifier samlRef = new SamlKeyIdentifier(msg.getSOAPPart());
246: samlRef.setReferenceValue(assertion.getAssertionID());
247: str.setReference(samlRef);
248: impl.setAttachedSecurityTokenReference(str);
249: impl.setUnAttachedSecurityTokenReference(str);
250:
251: map.put(new String("12015"), impl);
252: //map.put(tok.getTokenId(), impl);
253: context.setIssuedTokenContextMap(map);
254: context.setAlgorithmSuite(alg);
255: context.setSecurityPolicy(pol);
256: //CallbackHandler handler = new PolicyCallbackHandler1("client");
257: SecurityEnvironment env = new DefaultSecurityEnvironmentImpl(
258: handler);
259: context.setSecurityEnvironment(env);
260:
261: SecurityAnnotator.secureMessage(context);
262:
263: SOAPMessage secMsg = context.getSOAPMessage();
264:
265: // now persist the message and read-back
266: FileOutputStream sentFile = new FileOutputStream("golden.msg");
267: secMsg.saveChanges();
268: saveMimeHeaders(secMsg, "golden.mh");
269: msg.writeTo(sentFile);
270: sentFile.close();
271:
272: // now create the message
273: SOAPMessage recMsg = constructMessage("golden.mh", "golden.msg");
274:
275: // verify
276: ProcessingContextImpl ctxImpl = verify(recMsg);
277: SOAPMessage vMsg = ctxImpl.getSOAPMessage();
278: vMsg.saveChanges();
279: ctxImpl.setSOAPMessage(vMsg);
280:
281: SOAPMessage newMsg = testResponse(ctxImpl);
282: newMsg.saveChanges();
283: context.setSOAPMessage(newMsg);
284:
285: }
286:
287: public static void saveMimeHeaders(SOAPMessage msg, String fileName)
288: throws IOException {
289:
290: FileOutputStream fos = new FileOutputStream(fileName);
291: ObjectOutputStream oos = new ObjectOutputStream(fos);
292:
293: Hashtable<String, Object> hashTable = new Hashtable<String, Object>();
294: MimeHeaders mimeHeaders = msg.getMimeHeaders();
295: Iterator iterator = mimeHeaders.getAllHeaders();
296:
297: while (iterator.hasNext()) {
298: MimeHeader mimeHeader = (MimeHeader) iterator.next();
299: hashTable.put(mimeHeader.getName(), mimeHeader.getValue());
300: }
301:
302: oos.writeObject(hashTable);
303: oos.flush();
304: oos.close();
305:
306: fos.flush();
307: fos.close();
308: }
309:
310: public static SOAPMessage constructMessage(String mimeHdrsFile,
311: String msgFile) throws Exception {
312: SOAPMessage message;
313:
314: MimeHeaders mimeHeaders = new MimeHeaders();
315: FileInputStream fis = new FileInputStream(msgFile);
316:
317: ObjectInputStream ois = new ObjectInputStream(
318: new FileInputStream(mimeHdrsFile));
319: Hashtable hashTable = (Hashtable) ois.readObject();
320: ois.close();
321:
322: if (hashTable.isEmpty()) {
323: // System.out.println("MimeHeaders Hashtable is empty");
324: } else {
325: for (int i = 0; i < hashTable.size(); i++) {
326: Enumeration keys = hashTable.keys();
327: Enumeration values = hashTable.elements();
328: while (keys.hasMoreElements()
329: && values.hasMoreElements()) {
330: String name = (String) keys.nextElement();
331: String value = (String) values.nextElement();
332: mimeHeaders.addHeader(name, value);
333: }
334: }
335: }
336:
337: MessageFactory messageFactory = MessageFactory.newInstance();
338: message = messageFactory.createMessage(mimeHeaders, fis);
339:
340: message.saveChanges();
341:
342: return message;
343: }
344:
345: public static ProcessingContextImpl verify(SOAPMessage msg)
346: throws Exception {
347: //Create processing context and set the soap
348: //message to be processed.
349: ProcessingContextImpl context = new ProcessingContextImpl();
350: context.setSOAPMessage(msg);
351: context.hasIssuedToken(true);
352: MessagePolicy pol = new MessagePolicy();
353: //pol.dumpMessages(true);
354: //pol.append(signaturePolicy);
355: context.setAlgorithmSuite(alg);
356:
357: context.setSecurityPolicy(pol);
358: CallbackHandler handler = new PolicyCallbackHandler1("server");
359: SecurityEnvironment env = new DefaultSecurityEnvironmentImpl(
360: handler);
361: context.setSecurityEnvironment(env);
362:
363: SecurityRecipient.validateMessage(context);
364:
365: //context.getSOAPMessage().writeTo(System.out);
366:
367: return context;
368: }
369:
370: private static Assertion createHOKAssertion(byte[] keyBytes,
371: Document doc) {
372:
373: Assertion assertion = null;
374: try {
375:
376: SAMLAssertionFactory factory = SAMLAssertionFactory
377: .newInstance(SAMLAssertionFactory.SAML1_1);
378:
379: // create the assertion id
380: String assertionID = String.valueOf(System
381: .currentTimeMillis());
382: String issuer = "CN=Assertion Issuer,OU=AI,O=Assertion Issuer,L=Waltham,ST=MA,C=US";
383:
384: GregorianCalendar c = new GregorianCalendar();
385: long beforeTime = c.getTimeInMillis();
386: // roll the time by one hour
387: long offsetHours = 60 * 60 * 1000;
388:
389: c.setTimeInMillis(beforeTime - offsetHours);
390: GregorianCalendar before = (GregorianCalendar) c.clone();
391:
392: c = new GregorianCalendar();
393: long afterTime = c.getTimeInMillis();
394: c.setTimeInMillis(afterTime + offsetHours);
395: GregorianCalendar after = (GregorianCalendar) c.clone();
396:
397: GregorianCalendar issueInstant = new GregorianCalendar();
398: // statements
399: List statements = new LinkedList();
400: NameIdentifier nmId = factory
401: .createNameIdentifier(
402: "CN=SAML User,OU=SU,O=SAML User,L=Los Angeles,ST=CA,C=US",
403: null, // not sure abt this value
404: "urn:oasis:names:tc:SAML:1.1:nameid-format:X509SubjectName");
405:
406: //default priv key cert req
407: SOAPElement elem = (SOAPElement) doc.createElementNS(
408: WSTrustConstants.WST_NAMESPACE, "wst:BinarySecret");
409: elem.addTextNode(Base64.encode(keyBytes));
410:
411: KeyInfoHeaderBlock kiHB = new KeyInfoHeaderBlock(doc);
412:
413: SOAPElement binSecret = null;
414: kiHB.addBinarySecret(elem);
415:
416: List subConfirmation = new ArrayList();
417: subConfirmation.add(senderVouchesConfirmation);
418:
419: SubjectConfirmation scf = factory
420: .createSubjectConfirmation(subConfirmation, null,
421: kiHB.getAsSoapElement());
422:
423: Subject subj = factory.createSubject(nmId, scf);
424:
425: List attributes = new LinkedList();
426: List attributeValues = new LinkedList();
427: attributeValues.add("ATTRIBUTE1");
428: attributes.add(factory.createAttribute("attribute1",
429: "urn:com:sun:xml:wss:attribute", attributeValues));
430:
431: statements.add(factory.createAttributeStatement(subj,
432: attributes));
433:
434: Conditions conditions = factory.createConditions(before,
435: after, null, null, null);
436:
437: assertion = factory.createAssertion(assertionID, issuer,
438: issueInstant, conditions, null, statements);
439: assertion.setMajorVersion(BigInteger.ONE);
440: assertion.setMinorVersion(BigInteger.ONE);
441:
442: return assertion;
443: } catch (Exception e) {
444: e.printStackTrace();
445: throw new RuntimeException(e);
446: }
447:
448: }
449:
450: private static SOAPMessage testResponse(
451: ProcessingContextImpl context) throws Exception {
452: SignaturePolicy signaturePolicy = new SignaturePolicy();
453: SignatureTarget st = new SignatureTarget();
454: st.setType("qname");
455: st.setDigestAlgorithm(DigestMethod.SHA1);
456: SignatureTarget.Transform trans = new SignatureTarget.Transform();
457: trans
458: .setTransform(MessageConstants.TRANSFORM_C14N_EXCL_OMIT_COMMENTS);
459: st.addTransform(trans);
460:
461: ((SignaturePolicy.FeatureBinding) signaturePolicy
462: .getFeatureBinding()).addTargetBinding(st);
463: ((SignaturePolicy.FeatureBinding) signaturePolicy
464: .getFeatureBinding())
465: .setCanonicalizationAlgorithm(MessageConstants.TRANSFORM_C14N_EXCL_OMIT_COMMENTS);
466:
467: IssuedTokenKeyBinding isKB = (IssuedTokenKeyBinding) signaturePolicy
468: .newIssuedTokenKeyBinding();
469: isKB.setIncludeToken(Token.INCLUDE_NEVER);
470:
471: DerivedTokenKeyBinding dktSigKB = (DerivedTokenKeyBinding) signaturePolicy
472: .newDerivedTokenKeyBinding();
473: dktSigKB.setOriginalKeyBinding(isKB);
474:
475: EncryptionPolicy encryptPolicy = new EncryptionPolicy();
476: EncryptionTarget et = new EncryptionTarget();
477: et.setType("qname");
478: ((EncryptionPolicy.FeatureBinding) encryptPolicy
479: .getFeatureBinding()).addTargetBinding(st);
480: ((EncryptionPolicy.FeatureBinding) encryptPolicy
481: .getFeatureBinding())
482: .setDataEncryptionAlgorithm(MessageConstants.AES_BLOCK_ENCRYPTION_128);
483: IssuedTokenKeyBinding ieKB = (IssuedTokenKeyBinding) encryptPolicy
484: .newIssuedTokenKeyBinding();
485: ieKB.setIncludeToken(Token.INCLUDE_NEVER);
486: DerivedTokenKeyBinding dktEncKB = (DerivedTokenKeyBinding) encryptPolicy
487: .newDerivedTokenKeyBinding();
488: dktEncKB.setOriginalKeyBinding(ieKB);
489:
490: QName name = new QName("IssuedToken");
491: Token tok = new Token(name);
492: //isKB.setPolicyToken(tok);
493: //ieKB.setPolicyToken(tok);
494: isKB.setUUID(new String("11016"));
495: ieKB.setUUID(new String("11016"));
496: MessagePolicy pol = new MessagePolicy();
497: //pol.dumpMessages(true);
498: signaturePolicy.setUUID("22222");
499: pol.append(encryptPolicy);
500: pol.append(signaturePolicy);
501:
502: context.setSecurityPolicy(pol);
503:
504: SecurityAnnotator.secureMessage(context);
505:
506: return context.getSOAPMessage();
507: }
508: }
|