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:
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 TrustTest 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 map = new Hashtable();
127: private static AlgorithmSuite alg = null;
128:
129: public TrustTest(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(TrustTest.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: EncryptionPolicy encryptPolicy = new EncryptionPolicy();
174: EncryptionTarget et = new EncryptionTarget();
175: et.setType("qname");
176: ((EncryptionPolicy.FeatureBinding) encryptPolicy
177: .getFeatureBinding()).addTargetBinding(st);
178: ((EncryptionPolicy.FeatureBinding) encryptPolicy
179: .getFeatureBinding())
180: .setDataEncryptionAlgorithm(MessageConstants.AES_BLOCK_ENCRYPTION_128);
181: IssuedTokenKeyBinding ieKB = (IssuedTokenKeyBinding) encryptPolicy
182: .newIssuedTokenKeyBinding();
183:
184: QName name = new QName("IssuedToken");
185: Token tok = new Token(name);
186: //isKB.setPolicyToken(tok);
187: //ieKB.setPolicyToken(tok);
188: isKB.setUUID(new String("1011"));
189: ieKB.setUUID(new String("1011"));
190: MessagePolicy pol = new MessagePolicy();
191: //pol.dumpMessages(true);
192: signaturePolicy.setUUID("22222");
193: pol.append(encryptPolicy);
194: pol.append(signaturePolicy);
195:
196: SOAPMessage msg = MessageFactory.newInstance().createMessage();
197: SOAPBody body = msg.getSOAPBody();
198: SOAPBodyElement sbe = body.addBodyElement(SOAPFactory
199: .newInstance().createName("StockSymbol", "tru",
200: "http://fabrikam123.com/payloads"));
201: sbe.addTextNode("QQQ");
202:
203: //Create processing context and set the soap
204: //message to be processed.
205: ProcessingContextImpl context = new ProcessingContextImpl();
206: context.setSOAPMessage(msg);
207:
208: // create a new IssuedTokenContext
209: IssuedTokenContextImpl impl = new IssuedTokenContextImpl();
210:
211: SecureRandom rnd = SecureRandom.getInstance("SHA1PRNG");
212: byte[] keyBytes = new byte[16];
213: rnd.nextBytes(keyBytes);
214: impl.setProofKey(keyBytes);
215:
216: // create a SAML Token and set it here
217: Assertion assertion = createHOKAssertion(keyBytes, msg
218: .getSOAPPart());
219: Element samlElem = SAMLUtil.toElement(null, assertion);
220:
221: impl.setSecurityToken(new GenericToken(samlElem));
222: SecurityTokenReference str = new SecurityTokenReference(msg
223: .getSOAPPart());
224: KeyIdentifier samlRef = new SamlKeyIdentifier(msg.getSOAPPart());
225: samlRef.setReferenceValue(assertion.getAssertionID());
226: str.setReference(samlRef);
227: impl.setAttachedSecurityTokenReference(str);
228: impl.setUnAttachedSecurityTokenReference(str);
229:
230: map.put(new String("1011"), impl);
231: context.setIssuedTokenContextMap(map);
232: context.setAlgorithmSuite(alg);
233: context.setSecurityPolicy(pol);
234: CallbackHandler handler = new PolicyCallbackHandler1("client");
235: SecurityEnvironment env = new DefaultSecurityEnvironmentImpl(
236: handler);
237: context.setSecurityEnvironment(env);
238:
239: SecurityAnnotator.secureMessage(context);
240:
241: SOAPMessage secMsg = context.getSOAPMessage();
242:
243: // now persist the message and read-back
244: FileOutputStream sentFile = new FileOutputStream("golden.msg");
245: secMsg.saveChanges();
246: saveMimeHeaders(secMsg, "golden.mh");
247: msg.writeTo(sentFile);
248: sentFile.close();
249:
250: // now create the message
251: SOAPMessage recMsg = constructMessage("golden.mh", "golden.msg");
252:
253: // verify
254: /* uncomment after signing SAML Assertion
255: ProcessingContextImpl ctxImpl = verify(recMsg);
256: SOAPMessage vMsg = ctxImpl.getSOAPMessage();
257: vMsg.saveChanges();
258: ctxImpl.setSOAPMessage(vMsg);
259:
260: SOAPMessage newMsg = testResponse(ctxImpl);
261: newMsg.saveChanges();
262: context.setSOAPMessage(newMsg);
263: SecurityRecipient.validateMessage(context);
264: */
265: }
266:
267: public static void saveMimeHeaders(SOAPMessage msg, String fileName)
268: throws IOException {
269:
270: FileOutputStream fos = new FileOutputStream(fileName);
271: ObjectOutputStream oos = new ObjectOutputStream(fos);
272:
273: Hashtable hashTable = new Hashtable();
274: MimeHeaders mimeHeaders = msg.getMimeHeaders();
275: Iterator iterator = mimeHeaders.getAllHeaders();
276:
277: while (iterator.hasNext()) {
278: MimeHeader mimeHeader = (MimeHeader) iterator.next();
279: hashTable.put(mimeHeader.getName(), mimeHeader.getValue());
280: }
281:
282: oos.writeObject(hashTable);
283: oos.flush();
284: oos.close();
285:
286: fos.flush();
287: fos.close();
288: }
289:
290: public static SOAPMessage constructMessage(String mimeHdrsFile,
291: String msgFile) throws Exception {
292: SOAPMessage message;
293:
294: MimeHeaders mimeHeaders = new MimeHeaders();
295: FileInputStream fis = new FileInputStream(msgFile);
296:
297: ObjectInputStream ois = new ObjectInputStream(
298: new FileInputStream(mimeHdrsFile));
299: Hashtable hashTable = (Hashtable) ois.readObject();
300: ois.close();
301:
302: if (hashTable.isEmpty()) {
303: //System.out.println("MimeHeaders Hashtable is empty");
304: } else {
305: for (int i = 0; i < hashTable.size(); i++) {
306: Enumeration keys = hashTable.keys();
307: Enumeration values = hashTable.elements();
308: while (keys.hasMoreElements()
309: && values.hasMoreElements()) {
310: String name = (String) keys.nextElement();
311: String value = (String) values.nextElement();
312: mimeHeaders.addHeader(name, value);
313: }
314: }
315: }
316:
317: MessageFactory messageFactory = MessageFactory.newInstance();
318: message = messageFactory.createMessage(mimeHeaders, fis);
319:
320: message.saveChanges();
321:
322: return message;
323: }
324:
325: public static ProcessingContextImpl verify(SOAPMessage msg)
326: throws Exception {
327: //Create processing context and set the soap
328: //message to be processed.
329: ProcessingContextImpl context = new ProcessingContextImpl();
330: context.setSOAPMessage(msg);
331:
332: MessagePolicy pol = new MessagePolicy();
333: //pol.dumpMessages(true);
334: //pol.append(signaturePolicy);
335: context.setAlgorithmSuite(alg);
336:
337: context.setSecurityPolicy(pol);
338: CallbackHandler handler = new PolicyCallbackHandler1("server");
339: SecurityEnvironment env = new DefaultSecurityEnvironmentImpl(
340: handler);
341: context.setSecurityEnvironment(env);
342:
343: SecurityRecipient.validateMessage(context);
344:
345: //context.getSOAPMessage().writeTo(System.out);
346:
347: return context;
348: }
349:
350: private static Assertion createHOKAssertion(byte[] keyBytes,
351: Document doc) {
352:
353: Assertion assertion = null;
354: try {
355:
356: SAMLAssertionFactory factory = SAMLAssertionFactory
357: .newInstance(SAMLAssertionFactory.SAML1_1);
358:
359: // create the assertion id
360: String assertionID = String.valueOf(System
361: .currentTimeMillis());
362: String issuer = "CN=Assertion Issuer,OU=AI,O=Assertion Issuer,L=Waltham,ST=MA,C=US";
363:
364: GregorianCalendar c = new GregorianCalendar();
365: long beforeTime = c.getTimeInMillis();
366: // roll the time by one hour
367: long offsetHours = 60 * 60 * 1000;
368:
369: c.setTimeInMillis(beforeTime - offsetHours);
370: GregorianCalendar before = (GregorianCalendar) c.clone();
371:
372: c = new GregorianCalendar();
373: long afterTime = c.getTimeInMillis();
374: c.setTimeInMillis(afterTime + offsetHours);
375: GregorianCalendar after = (GregorianCalendar) c.clone();
376:
377: GregorianCalendar issueInstant = new GregorianCalendar();
378: // statements
379: List statements = new LinkedList();
380: NameIdentifier nmId = factory
381: .createNameIdentifier(
382: "CN=SAML User,OU=SU,O=SAML User,L=Los Angeles,ST=CA,C=US",
383: null, // not sure abt this value
384: "urn:oasis:names:tc:SAML:1.1:nameid-format:X509SubjectName");
385:
386: //default priv key cert req
387: SOAPElement elem = (SOAPElement) doc.createElementNS(
388: WSTrustConstants.WST_NAMESPACE, "wst:BinarySecret");
389: elem.addTextNode(Base64.encode(keyBytes));
390:
391: KeyInfoHeaderBlock kiHB = new KeyInfoHeaderBlock(doc);
392:
393: SOAPElement binSecret = null;
394: kiHB.addBinarySecret(elem);
395:
396: List subConfirmation = new ArrayList();
397: subConfirmation.add(senderVouchesConfirmation);
398:
399: SubjectConfirmation scf = factory
400: .createSubjectConfirmation(subConfirmation, null,
401: kiHB.getAsSoapElement());
402:
403: Subject subj = factory.createSubject(nmId, scf);
404:
405: List attributes = new LinkedList();
406: List attributeValues = new LinkedList();
407: attributeValues.add("ATTRIBUTE1");
408: attributes.add(factory.createAttribute("attribute1",
409: "urn:com:sun:xml:wss:attribute", attributeValues));
410:
411: statements.add(factory.createAttributeStatement(subj,
412: attributes));
413:
414: Conditions conditions = factory.createConditions(before,
415: after, null, null, null);
416:
417: assertion = factory.createAssertion(assertionID, issuer,
418: issueInstant, conditions, null, statements);
419: assertion.setMajorVersion(BigInteger.ONE);
420: assertion.setMinorVersion(BigInteger.ONE);
421:
422: return assertion;
423: } catch (Exception e) {
424: e.printStackTrace();
425: throw new RuntimeException(e);
426: }
427:
428: }
429:
430: private static SOAPMessage testResponse(
431: ProcessingContextImpl context) throws Exception {
432: SignaturePolicy signaturePolicy = new SignaturePolicy();
433: SignatureTarget st = new SignatureTarget();
434: st.setType("qname");
435: st.setDigestAlgorithm(DigestMethod.SHA1);
436: SignatureTarget.Transform trans = new SignatureTarget.Transform();
437: trans
438: .setTransform(MessageConstants.TRANSFORM_C14N_EXCL_OMIT_COMMENTS);
439: st.addTransform(trans);
440:
441: ((SignaturePolicy.FeatureBinding) signaturePolicy
442: .getFeatureBinding()).addTargetBinding(st);
443: ((SignaturePolicy.FeatureBinding) signaturePolicy
444: .getFeatureBinding())
445: .setCanonicalizationAlgorithm(MessageConstants.TRANSFORM_C14N_EXCL_OMIT_COMMENTS);
446:
447: IssuedTokenKeyBinding isKB = (IssuedTokenKeyBinding) signaturePolicy
448: .newIssuedTokenKeyBinding();
449:
450: EncryptionPolicy encryptPolicy = new EncryptionPolicy();
451: EncryptionTarget et = new EncryptionTarget();
452: et.setType("qname");
453: ((EncryptionPolicy.FeatureBinding) encryptPolicy
454: .getFeatureBinding()).addTargetBinding(st);
455: ((EncryptionPolicy.FeatureBinding) encryptPolicy
456: .getFeatureBinding())
457: .setDataEncryptionAlgorithm(MessageConstants.AES_BLOCK_ENCRYPTION_128);
458: IssuedTokenKeyBinding ieKB = (IssuedTokenKeyBinding) encryptPolicy
459: .newIssuedTokenKeyBinding();
460:
461: QName name = new QName("IssuedToken");
462: Token tok = new Token(name);
463: //isKB.setPolicyToken(tok);
464: isKB.setUUID(new String("20029"));
465: ieKB.setUUID(new String("20029"));
466: //ieKB.setPolicyToken(tok);
467: MessagePolicy pol = new MessagePolicy();
468: //pol.dumpMessages(true);
469: signaturePolicy.setUUID("22222");
470: pol.append(encryptPolicy);
471: pol.append(signaturePolicy);
472:
473: context.setSecurityPolicy(pol);
474:
475: SecurityAnnotator.secureMessage(context);
476:
477: return context.getSOAPMessage();
478: }
479: }
|