|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
*/ |
|
|
|
package sun.security.krb5.internal; |
|
|
|
import java.io.ByteArrayOutputStream; |
|
import java.io.IOException; |
|
import sun.security.krb5.*; |
|
import sun.security.krb5.internal.crypto.KeyUsage; |
|
import sun.security.krb5.internal.util.KerberosString; |
|
import sun.security.util.DerOutputStream; |
|
import sun.security.util.DerValue; |
|
|
|
/** |
|
* Implements the ASN.1 PA-FOR-USER type. |
|
* |
|
* <pre>{@code |
|
* padata-type ::= PA-FOR-USER |
|
* -- value 129 |
|
* padata-value ::= EncryptedData |
|
* -- PA-FOR-USER-ENC |
|
* PA-FOR-USER-ENC ::= SEQUENCE { |
|
* userName[0] PrincipalName, |
|
* userRealm[1] Realm, |
|
* cksum[2] Checksum, |
|
* auth-package[3] KerberosString |
|
* } |
|
* }</pre> |
|
* |
|
* <p> |
|
* This definition reflects MS-SFU. |
|
*/ |
|
|
|
public class PAForUserEnc { |
|
final public PrincipalName name; |
|
final private EncryptionKey key; |
|
final public static String AUTH_PACKAGE = "Kerberos"; |
|
|
|
public PAForUserEnc(PrincipalName name, EncryptionKey key) { |
|
this.name = name; |
|
this.key = key; |
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
*/ |
|
public PAForUserEnc(DerValue encoding, EncryptionKey key) |
|
throws Asn1Exception, KrbException, IOException { |
|
DerValue der = null; |
|
this.key = key; |
|
|
|
if (encoding.getTag() != DerValue.tag_Sequence) { |
|
throw new Asn1Exception(Krb5.ASN1_BAD_ID); |
|
} |
|
|
|
|
|
PrincipalName tmpName = null; |
|
der = encoding.getData().getDerValue(); |
|
if ((der.getTag() & 0x1F) == 0x00) { |
|
try { |
|
tmpName = new PrincipalName(der.getData().getDerValue(), |
|
new Realm("PLACEHOLDER")); |
|
} catch (RealmException re) { |
|
// Impossible |
|
} |
|
} else { |
|
throw new Asn1Exception(Krb5.ASN1_BAD_ID); |
|
} |
|
|
|
der = encoding.getData().getDerValue(); |
|
if ((der.getTag() & 0x1F) == 0x01) { |
|
try { |
|
Realm realm = new Realm(der.getData().getDerValue()); |
|
name = new PrincipalName( |
|
tmpName.getNameType(), tmpName.getNameStrings(), realm); |
|
} catch (RealmException re) { |
|
throw new IOException(re); |
|
} |
|
} else { |
|
throw new Asn1Exception(Krb5.ASN1_BAD_ID); |
|
} |
|
|
|
der = encoding.getData().getDerValue(); |
|
if ((der.getTag() & 0x1F) == 0x02) { |
|
// Deal with the checksum |
|
} else { |
|
throw new Asn1Exception(Krb5.ASN1_BAD_ID); |
|
} |
|
|
|
der = encoding.getData().getDerValue(); |
|
if ((der.getTag() & 0x1F) == 0x03) { |
|
String authPackage = new KerberosString(der.getData().getDerValue()).toString(); |
|
if (!authPackage.equalsIgnoreCase(AUTH_PACKAGE)) { |
|
throw new IOException("Incorrect auth-package"); |
|
} |
|
} else { |
|
throw new Asn1Exception(Krb5.ASN1_BAD_ID); |
|
} |
|
if (encoding.getData().available() > 0) |
|
throw new Asn1Exception(Krb5.ASN1_BAD_ID); |
|
} |
|
|
|
public byte[] asn1Encode() throws Asn1Exception, IOException { |
|
DerOutputStream bytes = new DerOutputStream(); |
|
bytes.write(DerValue.createTag(DerValue.TAG_CONTEXT, true, (byte)0x00), name.asn1Encode()); |
|
bytes.write(DerValue.createTag(DerValue.TAG_CONTEXT, true, (byte)0x01), name.getRealm().asn1Encode()); |
|
|
|
try { |
|
|
|
Checksum cks = new Checksum( |
|
Checksum.CKSUMTYPE_HMAC_MD5_ARCFOUR, |
|
getS4UByteArray(), |
|
key, |
|
KeyUsage.KU_PA_FOR_USER_ENC_CKSUM); |
|
bytes.write(DerValue.createTag(DerValue.TAG_CONTEXT, true, (byte)0x02), cks.asn1Encode()); |
|
} catch (KrbException ke) { |
|
throw new IOException(ke); |
|
} |
|
|
|
DerOutputStream temp = new DerOutputStream(); |
|
temp.putDerValue(new KerberosString(AUTH_PACKAGE).toDerValue()); |
|
bytes.write(DerValue.createTag(DerValue.TAG_CONTEXT, true, (byte)0x03), temp); |
|
|
|
temp = new DerOutputStream(); |
|
temp.write(DerValue.tag_Sequence, bytes); |
|
return temp.toByteArray(); |
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
*/ |
|
public byte[] getS4UByteArray() { |
|
try { |
|
ByteArrayOutputStream ba = new ByteArrayOutputStream(); |
|
ba.write(new byte[4]); |
|
for (String s: name.getNameStrings()) { |
|
ba.write(s.getBytes("UTF-8")); |
|
} |
|
ba.write(name.getRealm().toString().getBytes("UTF-8")); |
|
ba.write(AUTH_PACKAGE.getBytes("UTF-8")); |
|
byte[] output = ba.toByteArray(); |
|
int pnType = name.getNameType(); |
|
output[0] = (byte)(pnType & 0xff); |
|
output[1] = (byte)((pnType>>8) & 0xff); |
|
output[2] = (byte)((pnType>>16) & 0xff); |
|
output[3] = (byte)((pnType>>24) & 0xff); |
|
return output; |
|
} catch (IOException ioe) { |
|
|
|
throw new AssertionError("Cannot write ByteArrayOutputStream", ioe); |
|
} |
|
} |
|
|
|
public PrincipalName getName() { |
|
return name; |
|
} |
|
|
|
public String toString() { |
|
return "PA-FOR-USER: " + name; |
|
} |
|
} |