/* * File: SAMLArtifactType0001.java * */ package org.opensaml.artifact; import java.util.Arrays; import org.apache.commons.codec.binary.Base64; import org.apache.commons.codec.binary.Hex; import org.opensaml.artifact.Artifact; import org.opensaml.artifact.Artifact.Parser; import org.opensaml.artifact.Artifact.RemainingArtifact; import org.opensaml.artifact.Artifact.TypeCode; import org.opensaml.artifact.ArtifactParseException; import org.opensaml.artifact.SAMLArtifact; import org.opensaml.artifact.Util; /** *

This class implements a type 0x0001 artifact as * specified by SAML V1.1.

* *
TypeCode            := 0x0001
 *RemainingArtifact   := SourceId AssertionHandle
 *SourceId            := 20-byte_sequence
 *AssertionHandle     := 20-byte_sequence
* *

Thus a type 0x0001 artifact is of size 42 bytes * (unencoded).

* *

The SourceId is an arbitrary sequence * of bytes. In practice, the SourceId is * the SHA-1 hash of the IdP providerId.

* *

The AssertionHandle is a sequence * of random bytes that points to an * authentication assertion at the IdP.

* * @author Tom Scavo */ public class SAMLArtifactType0001 extends SAMLArtifact { /** * The type code of this Artifact object. */ public static final Artifact.TypeCode TYPE_CODE = new TypeCode( (byte) 0x00, (byte) 0x01 ); /** * This constructor initializes the * remainingArtifact property by calling * the corresponding constructor of this implementation * of Artifact.RemainingArtifact. *

* This constructor throws a NullArgumentException * or InvalidArgumentException if its argument is * null or invalid, respectively. These exceptions are unchecked. * * @param sourceId the desired source Id * of this SAMLArtifactType0001 object * * @see SAMLArtifactType0001.RemainingArtifact * @see org.opensaml.artifact.NullArgumentException * @see org.opensaml.artifact.InvalidArgumentException */ public SAMLArtifactType0001( byte[] sourceId ) { checkIdentifierArg( sourceId ); this.typeCode = TYPE_CODE; this.remainingArtifact = new RemainingArtifact( sourceId ); } /** * This constructor initializes the * remainingArtifact property by calling * the corresponding constructor of this implementation * of Artifact.RemainingArtifact. *

* This constructor throws a NullArgumentException * or InvalidArgumentException if any of its * arguments are null or invalid, respectively. * These exceptions are unchecked. * * @param sourceId the desired source Id * of this SAMLArtifactType0001 object * * @param assertionHandle the desired assertion handle * of this SAMLArtifactType0001 object * * @see SAMLArtifactType0001.RemainingArtifact * @see org.opensaml.artifact.NullArgumentException * @see org.opensaml.artifact.InvalidArgumentException */ public SAMLArtifactType0001( byte[] sourceId, byte[] assertionHandle ) { checkIdentifierArg( sourceId ); checkHandleArg( assertionHandle ); this.typeCode = TYPE_CODE; this.remainingArtifact = new RemainingArtifact( sourceId, assertionHandle ); } /** * This constructor initializes the * remainingArtifact property to the * given value. *

* This constructor throws an (unchecked) * NullArgumentException if its argument is null. * * @param remainingArtifact the desired value of * the remainingArtifact property * of this SAMLArtifactType0001 object * * @see SAMLArtifactType0001.RemainingArtifact * @see org.opensaml.artifact.NullArgumentException */ public SAMLArtifactType0001( Artifact.RemainingArtifact remainingArtifact ) { checkNullArg( remainingArtifact ); this.typeCode = TYPE_CODE; this.remainingArtifact = remainingArtifact; } /** * A convenience method that returns the * sourceId property of this implementation * of Artifact.RemainingArtifact. * * @return the sourceId property * * @see SAMLArtifactType0001.RemainingArtifact */ public byte[] getSourceId() { return ((RemainingArtifact) this.remainingArtifact).getSourceId(); } /** * A convenience method that returns the * assertionHandle property of this implementation * of Artifact.RemainingArtifact. * * @return the assertionHandle property * * @see SAMLArtifactType0001.RemainingArtifact */ public byte[] getAssertionHandle() { return ((RemainingArtifact) this.remainingArtifact).getAssertionHandle(); } /** * An implementation of Artifact.RemainingArtifact * for type 0x0001 artifacts (via extension of * SAMLArtifact.RemainingArtifact). * This class defines two properties * (sourceId and assertionHandle). */ public static final class RemainingArtifact extends SAMLArtifact.RemainingArtifact { private byte[] sourceId; private byte[] assertionHandle; /** * This constructor initializes a property * of this RemainingArtifact * object to the given value. *

* This constructor throws a NullArgumentException * or InvalidArgumentException if its argument is * null or invalid, respectively. These exceptions are unchecked. * * @param sourceId a source Id * * @see org.opensaml.artifact.NullArgumentException * @see org.opensaml.artifact.InvalidArgumentException */ public RemainingArtifact( byte[] sourceId ) { checkIdentifierArg( sourceId ); this.sourceId = sourceId; this.assertionHandle = Util.generateRandomBytes( HANDLE_LENGTH ); } /** * This constructor initializes the properties * of this RemainingArtifact * object to the given values. *

* This constructor throws a NullArgumentException * or InvalidArgumentException if any of its * arguments are null or invalid, respectively. * These exceptions are unchecked. * * @param sourceId a source Id * @param assertionHandle an assertion handle * * @see org.opensaml.artifact.NullArgumentException * @see org.opensaml.artifact.InvalidArgumentException */ public RemainingArtifact( byte[] sourceId, byte[] assertionHandle ) { checkIdentifierArg( sourceId ); checkHandleArg( assertionHandle ); this.sourceId = sourceId; this.assertionHandle = assertionHandle; } /** * Get the sourceId property of this * Artifact.RemainingArtifact object. * * return the sourceId property */ public byte[] getSourceId() { return this.sourceId; } /** * Get the assertionHandle property of this * Artifact.RemainingArtifact object. * * return the assertionHandle property */ public byte[] getAssertionHandle() { return this.assertionHandle; } public int size() { return this.sourceId.length + this.assertionHandle.length; } public byte[] getBytes() { byte[] bytes0 = this.sourceId; byte[] bytes1 = this.assertionHandle; return Util.concat( bytes0, bytes1 ); } public int hashCode() { return this.sourceId.hashCode() & this.assertionHandle.hashCode(); } } /** * An implementation of Artifact.Parser * for type 0x0001 artifacts. */ public static final class Parser implements Artifact.Parser { /** * Parse the given encoded string. * * @param s the encoded string * * @return an artifact that may be cast to type * SAMLArtifactType0001 * * @exception org.opensaml.artifact.ArtifactParseException * if the length of the decoded string is * not equal to the required length, or the * type code is incorrect * * @see org.apache.commons.codec.binary.Base64 */ public Artifact parse( String s ) throws ArtifactParseException { // check total length: byte[] bytes = Base64.decodeBase64( s.getBytes() ); int expectedLength = 2 + IDENTIFIER_LENGTH + HANDLE_LENGTH; if ( bytes.length != expectedLength ) { throw new ArtifactParseException( bytes.length, expectedLength ); } // check type code: TypeCode typeCode = new TypeCode( (byte) bytes[0], (byte) bytes[1] ); if ( ! typeCode.equals( TYPE_CODE ) ) { throw new ArtifactParseException( typeCode, TYPE_CODE ); } // create and return the artifact: byte[] sourceId = new byte[ IDENTIFIER_LENGTH ]; System.arraycopy( bytes, 2, sourceId, 0, IDENTIFIER_LENGTH ); byte[] assertionHandle = new byte[ HANDLE_LENGTH ]; System.arraycopy( bytes, 2 + IDENTIFIER_LENGTH, assertionHandle, 0, HANDLE_LENGTH ); return new SAMLArtifactType0001( sourceId, assertionHandle ); } } }