use of sun.security.krb5.internal.ktab.KeyTab in project jdk8u_jdk by JetBrains.
the class KeyTab method getKeys.
/**
* Returns fresh keys for the given Kerberos principal.
* <p>
* Implementation of this method should make sure the returned keys match
* the latest content of the keytab file. The result is a newly created
* copy that can be modified by the caller without modifying the keytab
* object. The caller should {@link KerberosKey#destroy() destroy} the
* result keys after they are used.
* <p>
* Please note that the keytab file can be created after the
* {@code KeyTab} object is instantiated and its content may change over
* time. Therefore, an application should call this method only when it
* needs to use the keys. Any previous result from an earlier invocation
* could potentially be expired.
* <p>
* If there is any error (say, I/O error or format error)
* during the reading process of the KeyTab file, a saved result should be
* returned. If there is no saved result (say, this is the first time this
* method is called, or, all previous read attempts failed), an empty array
* should be returned. This can make sure the result is not drastically
* changed during the (probably slow) update of the keytab file.
* <p>
* Each time this method is called and the reading of the file succeeds
* with no exception (say, I/O error or file format error),
* the result should be saved for {@code principal}. The implementation can
* also save keys for other principals having keys in the same keytab object
* if convenient.
* <p>
* Any unsupported key read from the keytab is ignored and not included
* in the result.
* <p>
* If this keytab is bound to a specific principal, calling this method on
* another principal will return an empty array.
*
* @param principal the Kerberos principal, must not be null.
* @return the keys (never null, may be empty)
* @throws NullPointerException if the {@code principal}
* argument is null
* @throws SecurityException if a security manager exists and the read
* access to the keytab file is not permitted
*/
public KerberosKey[] getKeys(KerberosPrincipal principal) {
try {
if (princ != null && !principal.equals(princ)) {
return new KerberosKey[0];
}
PrincipalName pn = new PrincipalName(principal.getName());
EncryptionKey[] keys = takeSnapshot().readServiceKeys(pn);
KerberosKey[] kks = new KerberosKey[keys.length];
for (int i = 0; i < kks.length; i++) {
Integer tmp = keys[i].getKeyVersionNumber();
kks[i] = new KerberosKey(principal, keys[i].getBytes(), keys[i].getEType(), tmp == null ? 0 : tmp.intValue());
keys[i].destroy();
}
return kks;
} catch (RealmException re) {
return new KerberosKey[0];
}
}
use of sun.security.krb5.internal.ktab.KeyTab in project jdk8u_jdk by JetBrains.
the class FileKeyTab method main.
public static void main(String[] args) throws Exception {
String name = "ktab";
KeyTab kt = KeyTab.create(name);
kt.addEntry(new PrincipalName("a@A"), "x".toCharArray(), 1, true);
kt.save();
check(name);
check("FILE:" + name);
name = new File(name).getAbsolutePath().toString();
check(name);
check("FILE:" + name);
// The bug reporter uses this style, should only work for
// absolute path
check("FILE:/" + name);
}
use of sun.security.krb5.internal.ktab.KeyTab in project jdk8u_jdk by JetBrains.
the class KeyTabInputStream method readEntry.
KeyTabEntry readEntry(int entryLen, int ktVersion) throws IOException, RealmException {
index = entryLen;
if (index == 0) {
//in native implementation, when the last entry is deleted, a byte 0 is left.
return null;
}
if (index < 0) {
//in native implementation, when one of the entries is deleted, the entry length turns to be negative, and
//the fields are left with 0 bytes
skip(Math.abs(index));
return null;
}
//the number of service names.
int principalNum = read(2);
index -= 2;
if (ktVersion == KRB5_KT_VNO_1) {
//V1 includes realm in the count.
principalNum -= 1;
}
Realm realm = new Realm(readName());
String[] nameParts = new String[principalNum];
for (int i = 0; i < principalNum; i++) {
nameParts[i] = readName();
}
int nameType = read(4);
index -= 4;
PrincipalName service = new PrincipalName(nameType, nameParts, realm);
KerberosTime timeStamp = readTimeStamp();
int keyVersion = read() & 0xff;
index -= 1;
int keyType = read(2);
index -= 2;
int keyLength = read(2);
index -= 2;
byte[] keyblock = readKey(keyLength);
index -= keyLength;
// right, otherwise trust the new nonzero value.
if (index >= 4) {
int extKvno = read(4);
if (extKvno != 0) {
keyVersion = extKvno;
}
index -= 4;
}
// if index is negative, the keytab format must be wrong.
if (index < 0) {
throw new RealmException("Keytab is corrupted");
}
// ignore the left bytes.
skip(index);
return new KeyTabEntry(service, realm, timeStamp, keyVersion, keyType, keyblock);
}
use of sun.security.krb5.internal.ktab.KeyTab in project jdk8u_jdk by JetBrains.
the class KerberosClientKeyExchangeImpl method init.
/**
* Creates an instance of KerberosClientKeyExchange from its ASN.1 encoding.
* Used by ServerHandshaker to verify and obtain premaster secret.
*
* @param protocolVersion current protocol version
* @param clientVersion version requested by client in its ClientHello;
* used by premaster secret version check
* @param rand random number generator used for generating random
* premaster secret if ticket and/or premaster verification fails
* @param input inputstream from which to get ASN.1-encoded KerberosWrapper
* @param acc the AccessControlContext of the handshaker
* @param serviceCreds server's creds
*/
@Override
public void init(ProtocolVersion protocolVersion, ProtocolVersion clientVersion, SecureRandom rand, HandshakeInStream input, AccessControlContext acc, Object serviceCreds) throws IOException {
// Read ticket
encodedTicket = input.getBytes16();
if (debug != null && Debug.isOn("verbose")) {
Debug.println(System.out, "encoded Kerberos service ticket", encodedTicket);
}
EncryptionKey sessionKey = null;
try {
Ticket t = new Ticket(encodedTicket);
EncryptedData encPart = t.encPart;
PrincipalName ticketSname = t.sname;
final ServiceCreds creds = (ServiceCreds) serviceCreds;
final KerberosPrincipal princ = new KerberosPrincipal(ticketSname.toString());
// For bound service, permission already checked at setup
if (creds.getName() == null) {
SecurityManager sm = System.getSecurityManager();
try {
if (sm != null) {
// Eliminate dependency on ServicePermission
sm.checkPermission(Krb5Helper.getServicePermission(ticketSname.toString(), "accept"), acc);
}
} catch (SecurityException se) {
serviceCreds = null;
// Do not destroy keys. Will affect Subject
if (debug != null && Debug.isOn("handshake")) {
System.out.println("Permission to access Kerberos" + " secret key denied");
}
throw new IOException("Kerberos service not allowedy");
}
}
KerberosKey[] serverKeys = AccessController.doPrivileged(new PrivilegedAction<KerberosKey[]>() {
@Override
public KerberosKey[] run() {
return creds.getKKeys(princ);
}
});
if (serverKeys.length == 0) {
throw new IOException("Found no key for " + princ + (creds.getName() == null ? "" : (", this keytab is for " + creds.getName() + " only")));
}
/*
* permission to access and use the secret key of the Kerberized
* "host" service is done in ServerHandshaker.getKerberosKeys()
* to ensure server has the permission to use the secret key
* before promising the client
*/
// See if we have the right key to decrypt the ticket to get
// the session key.
int encPartKeyType = encPart.getEType();
Integer encPartKeyVersion = encPart.getKeyVersionNumber();
KerberosKey dkey = null;
try {
dkey = findKey(encPartKeyType, encPartKeyVersion, serverKeys);
} catch (KrbException ke) {
// a kvno mismatch
throw new IOException("Cannot find key matching version number", ke);
}
if (dkey == null) {
// %%% Should print string repr of etype
throw new IOException("Cannot find key of appropriate type" + " to decrypt ticket - need etype " + encPartKeyType);
}
EncryptionKey secretKey = new EncryptionKey(encPartKeyType, dkey.getEncoded());
// Decrypt encPart using server's secret key
byte[] bytes = encPart.decrypt(secretKey, KeyUsage.KU_TICKET);
// Reset data stream after decryption, remove redundant bytes
byte[] temp = encPart.reset(bytes);
EncTicketPart encTicketPart = new EncTicketPart(temp);
// Record the Kerberos Principals
peerPrincipal = new KerberosPrincipal(encTicketPart.cname.getName());
localPrincipal = new KerberosPrincipal(ticketSname.getName());
sessionKey = encTicketPart.key;
if (debug != null && Debug.isOn("handshake")) {
System.out.println("server principal: " + ticketSname);
System.out.println("cname: " + encTicketPart.cname.toString());
}
} catch (IOException e) {
throw e;
} catch (Exception e) {
if (debug != null && Debug.isOn("handshake")) {
System.out.println("KerberosWrapper error getting session key," + " generating random secret (" + e.getMessage() + ")");
}
sessionKey = null;
}
// XXX Read and ignore authenticator
input.getBytes16();
if (sessionKey != null) {
preMaster = new KerberosPreMasterSecret(protocolVersion, clientVersion, rand, input, sessionKey);
} else {
// Generate bogus premaster secret
preMaster = new KerberosPreMasterSecret(clientVersion, rand);
}
}
use of sun.security.krb5.internal.ktab.KeyTab in project jdk8u_jdk by JetBrains.
the class SSL method main.
public static void main(String[] args) throws Exception {
// reset the security property to make sure that the algorithms
// and keys used in this test are not disabled.
Security.setProperty("jdk.tls.disabledAlgorithms", "");
krb5Cipher = args[0];
boolean unbound = args.length > 1;
System.setSecurityManager(new SSL());
KDC kdc = KDC.create(OneKDC.REALM);
server = "host." + OneKDC.REALM.toLowerCase(Locale.US);
if (args.length > 2) {
sniHostname = "test." + server;
sniMatcherPattern = ".*";
}
kdc.addPrincipal(OneKDC.USER, OneKDC.PASS);
kdc.addPrincipalRandKey("krbtgt/" + OneKDC.REALM);
KDC.saveConfig(OneKDC.KRB5_CONF, kdc);
System.setProperty("java.security.krb5.conf", OneKDC.KRB5_CONF);
// Add 3 versions of keys into keytab
KeyTab ktab = KeyTab.create(OneKDC.KTAB);
String serviceName = null;
if (sniHostname != null) {
serviceName = "host/" + sniHostname;
} else {
serviceName = "host/" + server;
}
PrincipalName service = new PrincipalName(serviceName, PrincipalName.KRB_NT_SRV_HST);
ktab.addEntry(service, "pass1".toCharArray(), 1, true);
ktab.addEntry(service, "pass2".toCharArray(), 2, true);
ktab.addEntry(service, "pass3".toCharArray(), 3, true);
ktab.save();
// and use the middle one as the real key
kdc.addPrincipal(serviceName, "pass2".toCharArray());
// JAAS config entry name ssl
System.setProperty("java.security.auth.login.config", OneKDC.JAAS_CONF);
File f = new File(OneKDC.JAAS_CONF);
FileOutputStream fos = new FileOutputStream(f);
fos.write(("ssl {\n" + " com.sun.security.auth.module.Krb5LoginModule required\n" + (unbound ? " principal=*\n" : " principal=\"" + serviceName + "\"\n") + " useKeyTab=true\n" + " keyTab=" + OneKDC.KTAB + "\n" + " isInitiator=false\n" + " storeKey=true;\n};\n").getBytes());
fos.close();
Context c;
final Context s = Context.fromJAAS("ssl");
s.startAsServer(GSSUtil.GSS_KRB5_MECH_OID);
Thread server = new Thread(new Runnable() {
public void run() {
try {
s.doAs(new JsseServerAction(), null);
} catch (Exception e) {
e.printStackTrace();
serverState = 2;
}
}
});
server.setDaemon(true);
server.start();
while (serverState == 0) {
Thread.sleep(50);
}
if (serverState == 2) {
throw new Exception("Server already failed");
}
c = Context.fromUserPass(OneKDC.USER, OneKDC.PASS, false);
c.startAsClient(serviceName, GSSUtil.GSS_KRB5_MECH_OID);
c.doAs(new JsseClientAction(), null);
// Add another version of key, make sure it can be loaded
Thread.sleep(2000);
ktab = KeyTab.getInstance(OneKDC.KTAB);
ktab.addEntry(service, "pass4".toCharArray(), 4, true);
ktab.save();
kdc.addPrincipal(serviceName, "pass4".toCharArray());
c = Context.fromUserPass(OneKDC.USER, OneKDC.PASS, false);
c.startAsClient(serviceName, GSSUtil.GSS_KRB5_MECH_OID);
c.doAs(new JsseClientAction(), null);
// implementation related.
if (unbound) {
// and checks "accept". Second connection resume.
if (!permChecks.equals("IA")) {
throw new Exception();
}
} else {
// client then checks "initiate". Second connection resume.
if (!permChecks.equals("AAI")) {
throw new Exception();
}
}
}
Aggregations