Skip to content

Commit

Permalink
Complete Mechanism Name generation.
Browse files Browse the repository at this point in the history
  • Loading branch information
adiaholic committed Jan 29, 2020
1 parent 30004d8 commit 644a43a
Show file tree
Hide file tree
Showing 4 changed files with 54 additions and 34 deletions.
2 changes: 1 addition & 1 deletion smack-core/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ dependencies {
compile "org.jxmpp:jxmpp-core:$jxmppVersion"
compile "org.jxmpp:jxmpp-jid:$jxmppVersion"
compile "org.minidns:minidns-core:$miniDnsVersion"
compile "org.bouncycastle:bcprov-jdk15on:1.57"
compile "org.bouncycastle:bcprov-jdk15on:$bouncyCastleVersion"
testCompile project(':smack-xmlparser-stax')
testCompile project(':smack-xmlparser-xpp3')
testCompile "org.jxmpp:jxmpp-jid:$jxmppVersion:tests"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,14 +18,16 @@

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.jivesoftware.smack.util.SHA1;
import org.jivesoftware.smack.util.stringencoder.Base32;

import org.bouncycastle.asn1.ASN1ObjectIdentifier;

/**
Expand Down Expand Up @@ -64,37 +66,43 @@ public class GssApiMechanism extends SASLMechanism{
*/
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 generate a SHA-1 hash string over ASN1.DER.
byte[] ASN1_DER = getASN1DERencoding(objectIdentifier);
String sha1_hash = SHA1.hex(ASN1_DER);

// 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);
// Obtain first 55 bits of the SHA-1 hash.
String binary55Bits = getbinary55Bits(sha1_hash);

String mechanismName = GS2_PREFIX + getBase32Encoding(binarySHA1Hash);
// Make groups of 5 bits each
String[] binaryGroups = new String[11];
for (int i = 0 ; i < binary55Bits.length() / 5 ; i++) {
String binaryGroup = "";
for (int j = 0 ; j < 5 ; j++) {
binaryGroup += binary55Bits.charAt(5 * i + j);
}
// int decimalForGroup = Integer.parseInt(binaryGroup,2);

return mechanismName;
}
binaryGroups[i] = binaryGroup;
}

public String getBase32Encoding(String binarySHA1Hash) {
return binarySHA1Hash;
// Base32 encoding for the above binaryGroups
String base32Encoding = "";
for (int i = 0 ; i < 11 ; i++) {
int decimalValue = Integer.parseInt(binaryGroups[i], 2);
base32Encoding += Base32.encodeIntValue(decimalValue);
}
return GS2_PREFIX + base32Encoding;
}

public String getFirst_7_OctetsInBinary(String hashtext) {
// first_7_octets_to_binary_drop_last_bit = "00011100 11111000 11110100 00101011
// 01011010 10011111 1000000";
return hashtext;
private static String getbinary55Bits(String sha1_hash) {
// Get first 7 octets.
String first7Octets = sha1_hash.substring(0, 14);

// Convert first 7 octets of the sha1 hash into binary.
String binaryOctets = new BigInteger(first7Octets, 16).toString(2);

// Return first 55 bits of the binary hash.
return binaryOctets.substring(0, 55);
}

public byte[] getASN1DERencoding(String objectIdentifier) throws IOException {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ public String decode(String string) {
}

};
private static final String ALPHABET = "ABCDEFGHIJKLMNOPQRSTUVWXYZ2345678";
private static final String ALPHABET = "ABCDEFGHIJKLMNOPQRSTUVWXYZ234567";

public static StringEncoder<String> getStringEncoder() {
return base32Stringencoder;
Expand Down Expand Up @@ -159,6 +159,10 @@ public static String encode(String str) {
return res;
}

public static char encodeIntValue(int i) {
return ALPHABET.charAt(i);
}

private static int lenToPadding(int blocklen) {
switch (blocklen) {
case 1:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
import static org.junit.Assert.assertEquals;

import java.io.IOException;
import java.security.NoSuchAlgorithmException;

import org.jivesoftware.smack.test.util.SmackTestSuite;

Expand All @@ -27,14 +28,14 @@
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 SHA1_of_ASN_1_DER_in_HEX = "82d27325766bd6c845aa9325516afcff04b04360";

public static final String first_7_octets_to_binary_drop_last_bit = "1000001011010010011100110010010101110110011010111101011";
public static final String binary_in_group_of_5 = "10000 01011 01001 00111 00110 01001 01011 10110 01101 01111 01011";
public static final String decimal_of_each_group = "16 11 9 7 6 9 11 22 13 15 11";
public static final String base32Encoding = "QLJHGJLWNPL";
public static final String MECHANISM_NAME = "GS2-" + base32Encoding;

@Test
Expand All @@ -49,4 +50,11 @@ public void generateASN1DERTest() throws IOException {
}
assertEquals(ASN_1_DER_of_OID_in_HEX, asn1_der_of_oid_in_hex);
}

@Test
public void generateMechanismName() throws IOException, NoSuchAlgorithmException {
GssApiMechanism gssApiMechanism = new GssApiMechanism();
String mechanismName = gssApiMechanism.generateSASLMechanismNameFromGSSApiOIDs(OID);
assertEquals(MECHANISM_NAME, mechanismName);
}
}

0 comments on commit 644a43a

Please sign in to comment.