-
Notifications
You must be signed in to change notification settings - Fork 884
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Generate ASN.1 DER encoding for mechanism name.
- Loading branch information
Showing
6 changed files
with
356 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
29 changes: 29 additions & 0 deletions
29
smack-core/src/main/java/org/jivesoftware/smack/sasl/gssApi/GSS_Inquire_SASLname.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,29 @@ | ||
/** | ||
* | ||
* Copyright 2020 Aditya Borikar | ||
* | ||
* Licensed under the Apache License, Version 2.0 (the "License"); | ||
* you may not use this file except in compliance with the License. | ||
* You may obtain a copy of the License at | ||
* | ||
* http://www.apache.org/licenses/LICENSE-2.0 | ||
* | ||
* Unless required by applicable law or agreed to in writing, software | ||
* distributed under the License is distributed on an "AS IS" BASIS, | ||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
* See the License for the specific language governing permissions and | ||
* limitations under the License. | ||
*/ | ||
package org.jivesoftware.smack.sasl.gssApi; | ||
|
||
/** | ||
* If GSS_Inquire_SASLname_for_mech() fails and the GS2 implementation cannot | ||
* map the OID to a SASL mechanism name via some other means, then the | ||
* GS2 implementation MUST NOT use the given GSS-API mechanism. | ||
* @author adiaholic | ||
* | ||
*/ | ||
public abstract class GSS_Inquire_SASLname { | ||
|
||
public abstract boolean GSS_Inquire_SASLname_for_mech(); | ||
} |
196 changes: 196 additions & 0 deletions
196
smack-core/src/main/java/org/jivesoftware/smack/sasl/gssApi/GssApiMechanism.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,196 @@ | ||
/** | ||
* | ||
* Copyright 2020 Aditya Borikar | ||
* | ||
* Licensed under the Apache License, Version 2.0 (the "License"); | ||
* you may not use this file except in compliance with the License. | ||
* You may obtain a copy of the License at | ||
* | ||
* http://www.apache.org/licenses/LICENSE-2.0 | ||
* | ||
* Unless required by applicable law or agreed to in writing, software | ||
* distributed under the License is distributed on an "AS IS" BASIS, | ||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
* See the License for the specific language governing permissions and | ||
* limitations under the License. | ||
*/ | ||
package org.jivesoftware.smack.sasl.gssApi; | ||
|
||
import java.io.IOException; | ||
import java.math.BigInteger; | ||
import java.security.MessageDigest; | ||
import java.security.NoSuchAlgorithmException; | ||
|
||
import javax.security.auth.callback.CallbackHandler; | ||
|
||
import org.jivesoftware.smack.SmackException.SmackSaslException; | ||
import org.jivesoftware.smack.sasl.SASLMechanism; | ||
|
||
import org.bouncycastle.asn1.ASN1ObjectIdentifier; | ||
|
||
/** | ||
* Use of GSS-API mechanism in SASL by defining a new SASL mechanism family called GS2. | ||
* This mechanism offers a number of improvements over the previous "SASL/GSSAPI" mechanism. | ||
* In general, it uses fewer messages for authentication phase in some cases, and supports negotiable use of channel binding. | ||
* Only GSS-API mechanisms that support channel binding and mutual authentication are supported. | ||
* <br> | ||
* The absence of `PLUS` suffix in the name `GSS-API` suggests that the server doesn't support channel binding. | ||
* <br> | ||
* SASL implementations can use the GSS_Inquire_SASLname_for_mech call | ||
* to query for the SASL mechanism name of a GSS-API mechanism. | ||
* <br> | ||
* If the GSS_Inquire_SASLname_for_mech interface is not used, the GS2 | ||
* implementation needs some other mechanism to map mechanism Object | ||
* Identifiers (OIDs) to SASL names internally. | ||
* <br> | ||
* In this case, the implementation can only support the mechanisms for which it knows the | ||
* SASL name. | ||
* | ||
* @author adiaholic | ||
*/ | ||
public class GssApiMechanism extends SASLMechanism{ | ||
|
||
public static final String NAME = "GSS-API"; | ||
|
||
public static final String GS2_PREFIX = "GS2-"; | ||
|
||
private String objectID = null; | ||
/* | ||
* The SASL Mechanism name is concatenation of the string "GS2-" and the | ||
* Base32 encoding of the first 55 bits of the binary SHA-1 hash string | ||
* computed over the ASN.1 DER encoding | ||
* <br> | ||
* Note : Some older GSS-API mechanisms were not specified with a SASL GS2 mechanism name. | ||
*/ | ||
public String generateSASLMechanismNameFromGSSApiOIDs (String objectIdentifier) throws NoSuchAlgorithmException, IOException { | ||
|
||
/* | ||
* If any padding or non-alphabet characters are encountered, | ||
* the name is not a GS2 family mechanism name. | ||
* This name denotes that the server does not support channel binding, | ||
* because the suffix "-PLUS" is missing . | ||
*/ | ||
|
||
// To calculate the binary SHA-1 Hash | ||
MessageDigest md = MessageDigest.getInstance("SHA-1"); | ||
byte[] messageDigest = md.digest(getASN1DERencoding(objectIdentifier)); | ||
BigInteger no = new BigInteger(1, messageDigest); | ||
String hashtext = no.toString(16); | ||
while (hashtext.length() < 32) { | ||
hashtext = "0" + hashtext; | ||
} | ||
String binarySHA1Hash = getFirst_7_OctetsInBinary(hashtext); | ||
binarySHA1Hash = binarySHA1Hash.substring(0, 54); | ||
|
||
String mechanismName = GS2_PREFIX + getBase32Encoding(binarySHA1Hash); | ||
|
||
return mechanismName; | ||
} | ||
|
||
public String getBase32Encoding(String binarySHA1Hash) { | ||
return binarySHA1Hash; | ||
} | ||
|
||
public String getFirst_7_OctetsInBinary(String hashtext) { | ||
// first_7_octets_to_binary_drop_last_bit = "00011100 11111000 11110100 00101011 | ||
// 01011010 10011111 1000000"; | ||
return hashtext; | ||
} | ||
|
||
public byte[] getASN1DERencoding(String objectIdentifier) throws IOException { | ||
ASN1ObjectIdentifier asn1ObjectIdentifier = new ASN1ObjectIdentifier(objectIdentifier).intern(); | ||
byte[] encoded = asn1ObjectIdentifier.getEncoded(); | ||
return encoded; | ||
} | ||
|
||
/* | ||
* A GS2 mechanism that has a non-OID-derived SASL mechanism name is | ||
* said to have a "user-friendly SASL mechanism name". | ||
*/ | ||
public void generateSASLMechanismNameManually() { | ||
} | ||
|
||
@Override | ||
protected void authenticateInternal(CallbackHandler cbh) throws SmackSaslException { | ||
} | ||
|
||
@Override | ||
protected byte[] getAuthenticationText() throws SmackSaslException { | ||
/** | ||
* During the SASL authentication exchange for GS2, a number of messages | ||
* following the following format are sent between the client and server. On | ||
* success, this number is the same as the number of context tokens that the | ||
* GSS-API mechanism would normally require in order to establish a security | ||
* context. On failures, the exchange can be terminated early by any party. | ||
* | ||
* When using a GS2 mechanism the SASL client is always a GSS-API initiator and | ||
* the SASL server is always a GSS-API acceptor. The client calls | ||
* GSS_Init_sec_context and the server calls GSS_Accept_sec_context. | ||
* | ||
* All the SASL authentication messages exchanged are exactly the same as the | ||
* security context tokens of the GSS-API mechanism, except for the initial | ||
* security context token. | ||
* | ||
* The client and server MAY send GSS-API error tokens (tokens output by | ||
* GSS_Init_sec_context() or GSS_Accept_sec_context() when the major status code | ||
* is other than GSS_S_COMPLETE or GSS_S_CONTINUE_NEEDED). As this indicates an | ||
* error condition, after sending the token, the sending side should fail the | ||
* authentication. | ||
* | ||
* The initial security context token is modified as follows: | ||
* | ||
* o The initial context token header (see Section 3.1 of [RFC2743]) MUST be | ||
* removed if present. If the header is not present, the client MUST send a | ||
* "gs2-nonstd-flag" flag (see below). On the server side, this header MUST be | ||
* recomputed and restored prior to passing the token to GSS_Accept_sec_context, | ||
* except when the "gs2- nonstd-flag" is sent. | ||
* | ||
* o A GS2 header MUST be prefixed to the resulting initial context token. This | ||
* header has the form "gs2-header" given below in ABNF [RFC5234]. | ||
* | ||
* The figure below describes the permissible attributes, their use, and the | ||
* format of their values. All attribute names are single US-ASCII letters and | ||
* are case sensitive. | ||
* | ||
* The "gs2-cb-flag" signals the channel binding mode. One of "p", "n", or "y" | ||
* is used. A "p" means the client supports and used a channel binding, and the | ||
* name of the channel binding type is indicated. An "n" means that the client | ||
* does not support channel binding. A "y" means the client supports channel | ||
* binding, but believes the server does not support it, so it did not use a | ||
* channel binding. See the next section for more details. | ||
*/ | ||
|
||
// @Todo : Remove initial context token header if present | ||
|
||
// @Todo : If header is not present, the client must send a 'gs2-nonstd-flag'. | ||
|
||
// @Todo : GS2 header must be prefixed to the resulting initial context token. | ||
// This header has the form 'gs2-header' | ||
// ASN1InputStream input = new ASN1InputStream(objectID.getBytes()); | ||
|
||
return null; | ||
} | ||
|
||
@Override | ||
public String getName() { | ||
return NAME; | ||
} | ||
|
||
@Override | ||
public int getPriority() { | ||
return 0; | ||
} | ||
|
||
@Override | ||
protected void checkIfSuccessfulOrThrow() throws SmackSaslException { | ||
} | ||
|
||
@Override | ||
protected GssApiMechanism newInstance() { | ||
return new GssApiMechanism(); | ||
} | ||
|
||
public String getObjectID() { | ||
return objectID; | ||
} | ||
} |
58 changes: 58 additions & 0 deletions
58
smack-core/src/main/java/org/jivesoftware/smack/sasl/gssApi/GssApiPlusMechanism.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,58 @@ | ||
/** | ||
* | ||
* Copyright 2020 Aditya Borikar | ||
* | ||
* Licensed under the Apache License, Version 2.0 (the "License"); | ||
* you may not use this file except in compliance with the License. | ||
* You may obtain a copy of the License at | ||
* | ||
* http://www.apache.org/licenses/LICENSE-2.0 | ||
* | ||
* Unless required by applicable law or agreed to in writing, software | ||
* distributed under the License is distributed on an "AS IS" BASIS, | ||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
* See the License for the specific language governing permissions and | ||
* limitations under the License. | ||
*/ | ||
package org.jivesoftware.smack.sasl.gssApi; | ||
|
||
import javax.security.auth.callback.CallbackHandler; | ||
|
||
import org.jivesoftware.smack.SmackException.SmackSaslException; | ||
import org.jivesoftware.smack.sasl.SASLMechanism; | ||
|
||
/** | ||
* The plus inside the GSS-API-plus mechanism name suggests that the server supports channel binding. | ||
* | ||
* @author adiaholic | ||
*/ | ||
public class GssApiPlusMechanism extends SASLMechanism{ | ||
|
||
@Override | ||
protected void authenticateInternal(CallbackHandler cbh) throws SmackSaslException { | ||
} | ||
|
||
@Override | ||
protected byte[] getAuthenticationText() throws SmackSaslException { | ||
return null; | ||
} | ||
|
||
@Override | ||
public String getName() { | ||
return null; | ||
} | ||
|
||
@Override | ||
public int getPriority() { | ||
return 0; | ||
} | ||
|
||
@Override | ||
protected void checkIfSuccessfulOrThrow() throws SmackSaslException { | ||
} | ||
|
||
@Override | ||
protected SASLMechanism newInstance() { | ||
return null; | ||
} | ||
} |
20 changes: 20 additions & 0 deletions
20
smack-core/src/main/java/org/jivesoftware/smack/sasl/gssApi/package-info.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,20 @@ | ||
/** | ||
* | ||
* Copyright 2020 Aditya Borikar | ||
* | ||
* Licensed under the Apache License, Version 2.0 (the "License"); | ||
* you may not use this file except in compliance with the License. | ||
* You may obtain a copy of the License at | ||
* | ||
* http://www.apache.org/licenses/LICENSE-2.0 | ||
* | ||
* Unless required by applicable law or agreed to in writing, software | ||
* distributed under the License is distributed on an "AS IS" BASIS, | ||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
* See the License for the specific language governing permissions and | ||
* limitations under the License. | ||
*/ | ||
package org.jivesoftware.smack.sasl.gssApi; | ||
/* | ||
* Implementation for RFC 5801 : GSSAPI for SASL - The GS2 Mechanism Family. | ||
*/ |
52 changes: 52 additions & 0 deletions
52
smack-core/src/test/java/org/jivesoftware/smack/sasl/gssApi/GssApiMechanismTest.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,52 @@ | ||
/** | ||
* | ||
* Copyright 2020 Aditya Borikar | ||
* | ||
* Licensed under the Apache License, Version 2.0 (the "License"); | ||
* you may not use this file except in compliance with the License. | ||
* You may obtain a copy of the License at | ||
* | ||
* http://www.apache.org/licenses/LICENSE-2.0 | ||
* | ||
* Unless required by applicable law or agreed to in writing, software | ||
* distributed under the License is distributed on an "AS IS" BASIS, | ||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
* See the License for the specific language governing permissions and | ||
* limitations under the License. | ||
*/ | ||
package org.jivesoftware.smack.sasl.gssApi; | ||
|
||
import static org.junit.Assert.assertEquals; | ||
|
||
import java.io.IOException; | ||
|
||
import org.jivesoftware.smack.test.util.SmackTestSuite; | ||
|
||
import org.junit.Test; | ||
|
||
public class GssApiMechanismTest extends SmackTestSuite { | ||
|
||
public static final String OID = "1.2.840.113554.1.2.2"; | ||
|
||
public static final String ASN_1_DER_of_OID_in_HEX = "06092A864886F712010202"; | ||
|
||
public static final String SHA1_of_ASN_1_DER_in_HEX = "1c f8 f4 2b 5a 9f 80 fa e9 f8 31 22 6d 5d 9d 56 27 86 61 ad"; | ||
public static final String first_7_octets_to_binary_drop_last_bit = "00011100 11111000 11110100 00101011 01011010 10011111 1000000"; | ||
public static final String binary_in_group_of_5 = "00011 10011 11100 01111 01000 01010 11010 11010 10011 11110 00000"; | ||
public static final String decimal_of_each_group = "3 19 28 15 8 10 26 26 19 30 0"; | ||
public static final String base32Encoding = "DT4PIK22T6A"; | ||
public static final String MECHANISM_NAME = "GS2-" + base32Encoding; | ||
|
||
@Test | ||
public void generateASN1DERTest() throws IOException { | ||
GssApiMechanism gssApiMechanism = new GssApiMechanism(); | ||
byte[] asn1DERencoding = gssApiMechanism.getASN1DERencoding(OID); | ||
|
||
String asn1_der_of_oid_in_hex = ""; | ||
|
||
for (byte b : asn1DERencoding) { | ||
asn1_der_of_oid_in_hex += String.format("%02X", b); | ||
} | ||
assertEquals(ASN_1_DER_of_OID_in_HEX, asn1_der_of_oid_in_hex); | ||
} | ||
} |
There is
$bouncyCastleVersion
inversion.gradle