You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@hc.apache.org by kw...@apache.org on 2017/03/16 16:07:27 UTC
svn commit: r1787213 - in
/httpcomponents/httpclient/branches/pull-66/httpclient/src/main/java/org/apache/http/impl/auth:
CredSspScheme.java CredSspTsRequest.java
Author: kwright
Date: Thu Mar 16 16:07:26 2017
New Revision: 1787213
URL: http://svn.apache.org/viewvc?rev=1787213&view=rev
Log:
Make the small helper class be a child class of the scheme
Removed:
httpcomponents/httpclient/branches/pull-66/httpclient/src/main/java/org/apache/http/impl/auth/CredSspTsRequest.java
Modified:
httpcomponents/httpclient/branches/pull-66/httpclient/src/main/java/org/apache/http/impl/auth/CredSspScheme.java
Modified: httpcomponents/httpclient/branches/pull-66/httpclient/src/main/java/org/apache/http/impl/auth/CredSspScheme.java
URL: http://svn.apache.org/viewvc/httpcomponents/httpclient/branches/pull-66/httpclient/src/main/java/org/apache/http/impl/auth/CredSspScheme.java?rev=1787213&r1=1787212&r2=1787213&view=diff
==============================================================================
--- httpcomponents/httpclient/branches/pull-66/httpclient/src/main/java/org/apache/http/impl/auth/CredSspScheme.java (original)
+++ httpcomponents/httpclient/branches/pull-66/httpclient/src/main/java/org/apache/http/impl/auth/CredSspScheme.java Thu Mar 16 16:07:26 2017
@@ -37,6 +37,7 @@ import java.security.cert.Certificate;
import java.security.cert.CertificateException;
import java.security.cert.X509Certificate;
import java.util.Base64;
+import java.util.Arrays;
import javax.net.ssl.SSLContext;
import javax.net.ssl.SSLEngine;
@@ -116,6 +117,7 @@ public class CredSspScheme extends AuthS
private State state;
private SSLEngine sslEngine;
+ private final NTLMEngineImpl ntlmEngine;
private NTLMEngineImpl.Type1Message type1Message;
private NTLMEngineImpl.Type2Message type2Message;
private NTLMEngineImpl.Type3Message type3Message;
@@ -136,8 +138,12 @@ public class CredSspScheme extends AuthS
private static boolean develTrace = false;
- public CredSspScheme()
- {
+ public CredSspScheme() {
+ this(new NTLMEngineImpl());
+ }
+
+ public CredSspScheme(final NTLMEngineImpl ntlmEngine) {
+ this.ntlmEngine = ntlmEngine;
state = State.UNINITIATED;
}
@@ -770,4 +776,283 @@ public class CredSspScheme extends AuthS
return state == State.CREDENTIALS_SENT;
}
+ /**
+ * Implementation of the TsRequest structure used in CredSSP protocol.
+ * It is specified in [MS-CPPS] section 2.2.1.
+ */
+ static class CredSspTsRequest
+ {
+
+ private static final int VERSION = 3;
+
+ private byte[] negoToken;
+ private byte[] authInfo;
+ private byte[] pubKeyAuth;
+
+
+ protected CredSspTsRequest()
+ {
+ super();
+ }
+
+
+ public static CredSspTsRequest createNegoToken( final byte[] negoToken )
+ {
+ final CredSspTsRequest req = new CredSspTsRequest();
+ req.negoToken = negoToken;
+ return req;
+ }
+
+
+ public static CredSspTsRequest createAuthInfo( final byte[] authInfo )
+ {
+ final CredSspTsRequest req = new CredSspTsRequest();
+ req.authInfo = authInfo;
+ return req;
+ }
+
+
+ public static CredSspTsRequest createDecoded( final ByteBuffer buf ) throws MalformedChallengeException
+ {
+ final CredSspTsRequest req = new CredSspTsRequest();
+ req.decode( buf );
+ return req;
+ }
+
+
+ public byte[] getNegoToken()
+ {
+ return negoToken;
+ }
+
+
+ public void setNegoToken( final byte[] negoToken )
+ {
+ this.negoToken = negoToken;
+ }
+
+
+ public byte[] getAuthInfo()
+ {
+ return authInfo;
+ }
+
+
+ public void setAuthInfo( final byte[] authInfo )
+ {
+ this.authInfo = authInfo;
+ }
+
+
+ public byte[] getPubKeyAuth()
+ {
+ return pubKeyAuth;
+ }
+
+
+ public void setPubKeyAuth( final byte[] pubKeyAuth )
+ {
+ this.pubKeyAuth = pubKeyAuth;
+ }
+
+
+ public void decode( final ByteBuffer buf ) throws MalformedChallengeException
+ {
+ negoToken = null;
+ authInfo = null;
+ pubKeyAuth = null;
+
+ DerUtil.getByteAndAssert( buf, 0x30, "initial sequence" );
+ DerUtil.parseLength( buf );
+
+ while ( buf.hasRemaining() )
+ {
+ final int contentTag = DerUtil.getAndAssertContentSpecificTag( buf, "content tag" );
+ DerUtil.parseLength( buf );
+ switch ( contentTag )
+ {
+ case 0:
+ processVersion( buf );
+ break;
+ case 1:
+ parseNegoTokens( buf );
+ break;
+ case 2:
+ parseAuthInfo( buf );
+ break;
+ case 3:
+ parsePubKeyAuth( buf );
+ break;
+ case 4:
+ processErrorCode( buf );
+ break;
+ default:
+ DerUtil.parseError( buf, "unexpected content tag " + contentTag );
+ }
+ }
+ }
+
+
+ private void processVersion( final ByteBuffer buf ) throws MalformedChallengeException
+ {
+ DerUtil.getByteAndAssert( buf, 0x02, "version type" );
+ DerUtil.getLengthAndAssert( buf, 1, "version length" );
+ DerUtil.getByteAndAssert( buf, VERSION, "wrong protocol version" );
+ }
+
+
+ private void parseNegoTokens( final ByteBuffer buf ) throws MalformedChallengeException
+ {
+ DerUtil.getByteAndAssert( buf, 0x30, "negoTokens sequence" );
+ DerUtil.parseLength( buf );
+ // I have seen both 0x30LL encoding and 0x30LL0x30LL encoding. Accept both.
+ byte bufByte = buf.get();
+ if ( bufByte == 0x30 )
+ {
+ DerUtil.parseLength( buf );
+ bufByte = buf.get();
+ }
+ if ( ( bufByte & 0xff ) != 0xa0 )
+ {
+ DerUtil.parseError( buf, "negoTokens: wrong content-specific tag " + String.format( "%02X", bufByte ) );
+ }
+ DerUtil.parseLength( buf );
+ DerUtil.getByteAndAssert( buf, 0x04, "negoToken type" );
+
+ final int tokenLength = DerUtil.parseLength( buf );
+ negoToken = new byte[tokenLength];
+ buf.get( negoToken );
+ }
+
+
+ private void parseAuthInfo( final ByteBuffer buf ) throws MalformedChallengeException
+ {
+ DerUtil.getByteAndAssert( buf, 0x04, "authInfo type" );
+ final int length = DerUtil.parseLength( buf );
+ authInfo = new byte[length];
+ buf.get( authInfo );
+ }
+
+
+ private void parsePubKeyAuth( final ByteBuffer buf ) throws MalformedChallengeException
+ {
+ DerUtil.getByteAndAssert( buf, 0x04, "pubKeyAuth type" );
+ final int length = DerUtil.parseLength( buf );
+ pubKeyAuth = new byte[length];
+ buf.get( pubKeyAuth );
+ }
+
+
+ private void processErrorCode( final ByteBuffer buf ) throws MalformedChallengeException
+ {
+ DerUtil.getLengthAndAssert( buf, 3, "error code length" );
+ DerUtil.getByteAndAssert( buf, 0x02, "error code type" );
+ DerUtil.getLengthAndAssert( buf, 1, "error code length" );
+ final byte errorCode = buf.get();
+ DerUtil.parseError( buf, "Error code " + errorCode );
+ }
+
+
+ public void encode( final ByteBuffer buf )
+ {
+ final ByteBuffer inner = ByteBuffer.allocate( buf.capacity() );
+
+ // version tag [0]
+ inner.put( ( byte ) ( 0x00 | 0xa0 ) );
+ inner.put( ( byte ) 3 ); // length
+
+ inner.put( ( byte ) ( 0x02 ) ); // INTEGER tag
+ inner.put( ( byte ) 1 ); // length
+ inner.put( ( byte ) VERSION ); // value
+
+ if ( negoToken != null )
+ {
+ int len = negoToken.length;
+ final byte[] negoTokenLengthBytes = DerUtil.encodeLength( len );
+ len += 1 + negoTokenLengthBytes.length;
+ final byte[] negoTokenLength1Bytes = DerUtil.encodeLength( len );
+ len += 1 + negoTokenLength1Bytes.length;
+ final byte[] negoTokenLength2Bytes = DerUtil.encodeLength( len );
+ len += 1 + negoTokenLength2Bytes.length;
+ final byte[] negoTokenLength3Bytes = DerUtil.encodeLength( len );
+ len += 1 + negoTokenLength3Bytes.length;
+ final byte[] negoTokenLength4Bytes = DerUtil.encodeLength( len );
+
+ inner.put( ( byte ) ( 0x01 | 0xa0 ) ); // negoData tag [1]
+ inner.put( negoTokenLength4Bytes ); // length
+
+ inner.put( ( byte ) ( 0x30 ) ); // SEQUENCE tag
+ inner.put( negoTokenLength3Bytes ); // length
+
+ inner.put( ( byte ) ( 0x30 ) ); // .. of SEQUENCE tag
+ inner.put( negoTokenLength2Bytes ); // length
+
+ inner.put( ( byte ) ( 0x00 | 0xa0 ) ); // negoToken tag [0]
+ inner.put( negoTokenLength1Bytes ); // length
+
+ inner.put( ( byte ) ( 0x04 ) ); // OCTET STRING tag
+ inner.put( negoTokenLengthBytes ); // length
+
+ inner.put( negoToken );
+ }
+
+ if ( authInfo != null )
+ {
+ final byte[] authInfoEncodedLength = DerUtil.encodeLength( authInfo.length );
+
+ inner.put( ( byte ) ( 0x02 | 0xa0 ) ); // authInfo tag [2]
+ inner.put( DerUtil.encodeLength( 1 + authInfoEncodedLength.length + authInfo.length ) ); // length
+
+ inner.put( ( byte ) ( 0x04 ) ); // OCTET STRING tag
+ inner.put( authInfoEncodedLength );
+ inner.put( authInfo );
+ }
+
+ if ( pubKeyAuth != null )
+ {
+ final byte[] pubKeyAuthEncodedLength = DerUtil.encodeLength( pubKeyAuth.length );
+
+ inner.put( ( byte ) ( 0x03 | 0xa0 ) ); // pubKeyAuth tag [3]
+ inner.put( DerUtil.encodeLength( 1 + pubKeyAuthEncodedLength.length + pubKeyAuth.length ) ); // length
+
+ inner.put( ( byte ) ( 0x04 ) ); // OCTET STRING tag
+ inner.put( pubKeyAuthEncodedLength );
+ inner.put( pubKeyAuth );
+ }
+
+ inner.flip();
+
+ // SEQUENCE tag
+ buf.put( ( byte ) ( 0x10 | 0x20 ) );
+ buf.put( DerUtil.encodeLength( inner.limit() ) );
+ buf.put( inner );
+ }
+
+
+ public String debugDump()
+ {
+ final StringBuilder sb = new StringBuilder( "TsRequest\n" );
+ sb.append( " negoToken:\n" );
+ sb.append( " " );
+ DebugUtil.dump( sb, negoToken );
+ sb.append( "\n" );
+ sb.append( " authInfo:\n" );
+ sb.append( " " );
+ DebugUtil.dump( sb, authInfo );
+ sb.append( "\n" );
+ sb.append( " pubKeyAuth:\n" );
+ sb.append( " " );
+ DebugUtil.dump( sb, pubKeyAuth );
+ return sb.toString();
+ }
+
+
+ @Override
+ public String toString()
+ {
+ return "TsRequest(negoToken=" + Arrays.toString( negoToken ) + ", authInfo="
+ + Arrays.toString( authInfo ) + ", pubKeyAuth=" + Arrays.toString( pubKeyAuth ) + ")";
+ }
+ }
+
}