Search in sources :

Example 11 with KrbException

use of sun.security.krb5.KrbException 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);
    }
}
Also used : Ticket(sun.security.krb5.internal.Ticket) KerberosTicket(javax.security.auth.kerberos.KerberosTicket) KerberosPrincipal(javax.security.auth.kerberos.KerberosPrincipal) ServiceCreds(sun.security.jgss.krb5.ServiceCreds) EncryptionKey(sun.security.krb5.EncryptionKey) PrincipalName(sun.security.krb5.PrincipalName) IOException(java.io.IOException) EncTicketPart(sun.security.krb5.internal.EncTicketPart) KrbException(sun.security.krb5.KrbException) PrivilegedActionException(java.security.PrivilegedActionException) IOException(java.io.IOException) KerberosKey(javax.security.auth.kerberos.KerberosKey) KrbException(sun.security.krb5.KrbException) EncryptedData(sun.security.krb5.EncryptedData)

Example 12 with KrbException

use of sun.security.krb5.KrbException in project jdk8u_jdk by JetBrains.

the class KDC method writeKtab.

/**
     * Writes or appends keys into a keytab.
     * <p>
     * Attention: This is the most basic one of a series of methods below on
     * keytab creation or modification. All these methods reference krb5.conf
     * settings. If you need to modify krb5.conf or switch to another krb5.conf
     * later, please call <code>Config.refresh()</code> again. For example:
     * <pre>
     * kdc.writeKtab("/etc/kdc/ktab", true);  // Config is initialized,
     * System.setProperty("java.security.krb5.conf", "/home/mykrb5.conf");
     * Config.refresh();
     * </pre>
     * Inside this method there are 2 places krb5.conf is used:
     * <ol>
     * <li> (Fatal) Generating keys: EncryptionKey.acquireSecretKeys
     * <li> (Has workaround) Creating PrincipalName
     * </ol>
     * @param tab the keytab file name
     * @param append true if append, otherwise, overwrite.
     * @param names the names to write into, write all if names is empty
     */
public void writeKtab(String tab, boolean append, String... names) throws IOException, KrbException {
    KeyTab ktab = append ? KeyTab.getInstance(tab) : KeyTab.create(tab);
    Iterable<String> entries = (names.length != 0) ? Arrays.asList(names) : passwords.keySet();
    for (String name : entries) {
        char[] pass = passwords.get(name);
        int kvno = 0;
        if (Character.isDigit(pass[pass.length - 1])) {
            kvno = pass[pass.length - 1] - '0';
        }
        PrincipalName pn = new PrincipalName(name, name.indexOf('/') < 0 ? PrincipalName.KRB_NT_UNKNOWN : PrincipalName.KRB_NT_SRV_HST);
        ktab.addEntry(pn, getSalt(pn), pass, kvno, true);
    }
    ktab.save();
}
Also used : KeyTab(sun.security.krb5.internal.ktab.KeyTab)

Example 13 with KrbException

use of sun.security.krb5.KrbException in project jdk8u_jdk by JetBrains.

the class KDC method processAsReq.

/**
     * Processes a AS_REQ and generates a AS_REP (or KRB_ERROR)
     * @param in the request
     * @return the response
     * @throws java.lang.Exception for various errors
     */
protected byte[] processAsReq(byte[] in) throws Exception {
    ASReq asReq = new ASReq(in);
    int[] eTypes = null;
    List<PAData> outPAs = new ArrayList<>();
    PrincipalName service = asReq.reqBody.sname;
    if (options.containsKey(KDC.Option.RESP_NT)) {
        service = new PrincipalName((int) options.get(KDC.Option.RESP_NT), service.getNameStrings(), Realm.getDefault());
    }
    try {
        System.out.println(realm + "> " + asReq.reqBody.cname + " sends AS-REQ for " + service + ", " + asReq.reqBody.kdcOptions);
        KDCReqBody body = asReq.reqBody;
        eTypes = KDCReqBodyDotEType(body);
        int eType = eTypes[0];
        EncryptionKey ckey = keyForUser(body.cname, eType, false);
        EncryptionKey skey = keyForUser(service, eType, true);
        if (options.containsKey(KDC.Option.ONLY_RC4_TGT)) {
            int tgtEType = EncryptedData.ETYPE_ARCFOUR_HMAC;
            boolean found = false;
            for (int i = 0; i < eTypes.length; i++) {
                if (eTypes[i] == tgtEType) {
                    found = true;
                    break;
                }
            }
            if (!found) {
                throw new KrbException(Krb5.KDC_ERR_ETYPE_NOSUPP);
            }
            skey = keyForUser(service, tgtEType, true);
        }
        if (ckey == null) {
            throw new KrbException(Krb5.KDC_ERR_ETYPE_NOSUPP);
        }
        if (skey == null) {
            // TODO
            throw new KrbException(Krb5.KDC_ERR_SUMTYPE_NOSUPP);
        }
        // Session key
        EncryptionKey key = generateRandomKey(eType);
        // Check time, TODO
        KerberosTime till = body.till;
        if (till == null) {
            // TODO
            throw new KrbException(Krb5.KDC_ERR_NEVER_VALID);
        } else if (till.isZero()) {
            till = new KerberosTime(new Date().getTime() + 1000 * 3600 * 11);
        }
        //body.from
        boolean[] bFlags = new boolean[Krb5.TKT_OPTS_MAX + 1];
        if (body.kdcOptions.get(KDCOptions.FORWARDABLE)) {
            List<String> sensitives = (List<String>) options.get(Option.SENSITIVE_ACCOUNTS);
            if (sensitives != null && sensitives.contains(body.cname.toString())) {
            // Cannot make FORWARDABLE
            } else {
                bFlags[Krb5.TKT_OPTS_FORWARDABLE] = true;
            }
        }
        if (body.kdcOptions.get(KDCOptions.RENEWABLE)) {
            bFlags[Krb5.TKT_OPTS_RENEWABLE] = true;
        //renew = new KerberosTime(new Date().getTime() + 1000 * 3600 * 24 * 7);
        }
        if (body.kdcOptions.get(KDCOptions.PROXIABLE)) {
            bFlags[Krb5.TKT_OPTS_PROXIABLE] = true;
        }
        if (body.kdcOptions.get(KDCOptions.POSTDATED)) {
            bFlags[Krb5.TKT_OPTS_POSTDATED] = true;
        }
        if (body.kdcOptions.get(KDCOptions.ALLOW_POSTDATE)) {
            bFlags[Krb5.TKT_OPTS_MAY_POSTDATE] = true;
        }
        bFlags[Krb5.TKT_OPTS_INITIAL] = true;
        // Creating PA-DATA
        DerValue[] pas2 = null, pas = null;
        if (options.containsKey(KDC.Option.DUP_ETYPE)) {
            int n = (Integer) options.get(KDC.Option.DUP_ETYPE);
            switch(n) {
                case // customer's case in 7067974
                1:
                    pas2 = new DerValue[] { new DerValue(new ETypeInfo2(1, null, null).asn1Encode()), new DerValue(new ETypeInfo2(1, "", null).asn1Encode()), new DerValue(new ETypeInfo2(1, realm, new byte[] { 1 }).asn1Encode()) };
                    pas = new DerValue[] { new DerValue(new ETypeInfo(1, null).asn1Encode()), new DerValue(new ETypeInfo(1, "").asn1Encode()), new DerValue(new ETypeInfo(1, realm).asn1Encode()) };
                    break;
                case // we still reject non-null s2kparams and prefer E2 over E
                2:
                    pas2 = new DerValue[] { new DerValue(new ETypeInfo2(1, realm, new byte[] { 1 }).asn1Encode()), new DerValue(new ETypeInfo2(1, null, null).asn1Encode()), new DerValue(new ETypeInfo2(1, "", null).asn1Encode()) };
                    pas = new DerValue[] { new DerValue(new ETypeInfo(1, realm).asn1Encode()), new DerValue(new ETypeInfo(1, null).asn1Encode()), new DerValue(new ETypeInfo(1, "").asn1Encode()) };
                    break;
                case // but only E is wrong
                3:
                    pas = new DerValue[] { new DerValue(new ETypeInfo(1, realm).asn1Encode()), new DerValue(new ETypeInfo(1, null).asn1Encode()), new DerValue(new ETypeInfo(1, "").asn1Encode()) };
                    break;
                case // we also ignore rc4-hmac
                4:
                    pas = new DerValue[] { new DerValue(new ETypeInfo(23, "ANYTHING").asn1Encode()), new DerValue(new ETypeInfo(1, null).asn1Encode()), new DerValue(new ETypeInfo(1, "").asn1Encode()) };
                    break;
                case // "" should be wrong, but we accept it now
                5:
                    // See s.s.k.internal.PAData$SaltAndParams
                    pas = new DerValue[] { new DerValue(new ETypeInfo(1, "").asn1Encode()), new DerValue(new ETypeInfo(1, null).asn1Encode()) };
                    break;
            }
        } else {
            int[] epas = eTypes;
            if (options.containsKey(KDC.Option.RC4_FIRST_PREAUTH)) {
                for (int i = 1; i < epas.length; i++) {
                    if (epas[i] == EncryptedData.ETYPE_ARCFOUR_HMAC) {
                        epas[i] = epas[0];
                        epas[0] = EncryptedData.ETYPE_ARCFOUR_HMAC;
                        break;
                    }
                }
                ;
            } else if (options.containsKey(KDC.Option.ONLY_ONE_PREAUTH)) {
                epas = new int[] { eTypes[0] };
            }
            pas2 = new DerValue[epas.length];
            for (int i = 0; i < epas.length; i++) {
                pas2[i] = new DerValue(new ETypeInfo2(epas[i], epas[i] == EncryptedData.ETYPE_ARCFOUR_HMAC ? null : getSalt(body.cname), null).asn1Encode());
            }
            boolean allOld = true;
            for (int i : eTypes) {
                if (i == EncryptedData.ETYPE_AES128_CTS_HMAC_SHA1_96 || i == EncryptedData.ETYPE_AES256_CTS_HMAC_SHA1_96) {
                    allOld = false;
                    break;
                }
            }
            if (allOld) {
                pas = new DerValue[epas.length];
                for (int i = 0; i < epas.length; i++) {
                    pas[i] = new DerValue(new ETypeInfo(epas[i], epas[i] == EncryptedData.ETYPE_ARCFOUR_HMAC ? null : getSalt(body.cname)).asn1Encode());
                }
            }
        }
        DerOutputStream eid;
        if (pas2 != null) {
            eid = new DerOutputStream();
            eid.putSequence(pas2);
            outPAs.add(new PAData(Krb5.PA_ETYPE_INFO2, eid.toByteArray()));
        }
        if (pas != null) {
            eid = new DerOutputStream();
            eid.putSequence(pas);
            outPAs.add(new PAData(Krb5.PA_ETYPE_INFO, eid.toByteArray()));
        }
        PAData[] inPAs = KDCReqDotPAData(asReq);
        if (inPAs == null || inPAs.length == 0) {
            Object preauth = options.get(Option.PREAUTH_REQUIRED);
            if (preauth == null || preauth.equals(Boolean.TRUE)) {
                throw new KrbException(Krb5.KDC_ERR_PREAUTH_REQUIRED);
            }
        } else {
            try {
                EncryptedData data = newEncryptedData(new DerValue(inPAs[0].getValue()));
                EncryptionKey pakey = keyForUser(body.cname, data.getEType(), false);
                data.decrypt(pakey, KeyUsage.KU_PA_ENC_TS);
            } catch (Exception e) {
                throw new KrbException(Krb5.KDC_ERR_PREAUTH_FAILED);
            }
            bFlags[Krb5.TKT_OPTS_PRE_AUTHENT] = true;
        }
        TicketFlags tFlags = new TicketFlags(bFlags);
        EncTicketPart enc = new EncTicketPart(tFlags, key, body.cname, new TransitedEncoding(1, new byte[0]), new KerberosTime(new Date()), body.from, till, body.rtime, body.addresses, null);
        Ticket t = new Ticket(service, new EncryptedData(skey, enc.asn1Encode(), KeyUsage.KU_TICKET));
        EncASRepPart enc_part = new EncASRepPart(key, new LastReq(new LastReqEntry[] { new LastReqEntry(0, new KerberosTime(new Date().getTime() - 10000)) }), // TODO: detect replay?
        body.getNonce(), new KerberosTime(new Date().getTime() + 1000 * 3600 * 24), // Next 5 and last MUST be same with ticket
        tFlags, new KerberosTime(new Date()), body.from, till, body.rtime, service, body.addresses);
        EncryptedData edata = new EncryptedData(ckey, enc_part.asn1Encode(), KeyUsage.KU_ENC_AS_REP_PART);
        ASRep asRep = new ASRep(outPAs.toArray(new PAData[outPAs.size()]), body.cname, t, edata);
        System.out.println("     Return " + asRep.cname + " ticket for " + asRep.ticket.sname + ", flags " + tFlags);
        DerOutputStream out = new DerOutputStream();
        out.write(DerValue.createTag(DerValue.TAG_APPLICATION, true, (byte) Krb5.KRB_AS_REP), asRep.asn1Encode());
        byte[] result = out.toByteArray();
        // Added feature:
        // Write the current issuing TGT into a ccache file specified
        // by the system property below.
        String ccache = System.getProperty("test.kdc.save.ccache");
        if (ccache != null) {
            asRep.encKDCRepPart = enc_part;
            sun.security.krb5.internal.ccache.Credentials credentials = new sun.security.krb5.internal.ccache.Credentials(asRep);
            CredentialsCache cache = CredentialsCache.create(asReq.reqBody.cname, ccache);
            if (cache == null) {
                throw new IOException("Unable to create the cache file " + ccache);
            }
            cache.update(credentials);
            cache.save();
        }
        return result;
    } catch (KrbException ke) {
        ke.printStackTrace(System.out);
        KRBError kerr = ke.getError();
        KDCReqBody body = asReq.reqBody;
        System.out.println("     Error " + ke.returnCode() + " " + ke.returnCodeMessage());
        byte[] eData = null;
        if (kerr == null) {
            if (ke.returnCode() == Krb5.KDC_ERR_PREAUTH_REQUIRED || ke.returnCode() == Krb5.KDC_ERR_PREAUTH_FAILED) {
                DerOutputStream bytes = new DerOutputStream();
                bytes.write(new PAData(Krb5.PA_ENC_TIMESTAMP, new byte[0]).asn1Encode());
                for (PAData p : outPAs) {
                    bytes.write(p.asn1Encode());
                }
                DerOutputStream temp = new DerOutputStream();
                temp.write(DerValue.tag_Sequence, bytes);
                eData = temp.toByteArray();
            }
            kerr = new KRBError(null, null, null, new KerberosTime(new Date()), 0, ke.returnCode(), body.cname, service, KrbException.errorMessage(ke.returnCode()), eData);
        }
        return kerr.asn1Encode();
    }
}
Also used : sun.security.krb5.internal(sun.security.krb5.internal) sun.security.krb5(sun.security.krb5) DerOutputStream(sun.security.util.DerOutputStream) CredentialsCache(sun.security.krb5.internal.ccache.CredentialsCache) DerValue(sun.security.util.DerValue) InvocationTargetException(java.lang.reflect.InvocationTargetException)

Example 14 with KrbException

use of sun.security.krb5.KrbException in project jdk8u_jdk by JetBrains.

the class ReplayCachePrecise method main.

public static void main(String[] args) throws Exception {
    AuthTimeWithHash a1 = new AuthTimeWithHash(client, server, time(0), 0, "1111111111111111");
    AuthTimeWithHash a2 = new AuthTimeWithHash(client, server, time(0), 0, "2222222222222222");
    KerberosTime now = new KerberosTime(time(0) * 1000L);
    // When all new styles, must exact match
    ReplayCache cache = ReplayCache.getInstance("dfl:./c1");
    cache.checkAndStore(now, a1);
    cache.checkAndStore(now, a2);
    // When only old style in cache, partial match
    cache = ReplayCache.getInstance("dfl:./c2");
    cache.checkAndStore(now, a1);
    // A small surgery to remove the new style from the cache file
    SeekableByteChannel ch = Files.newByteChannel(Paths.get("c2"), StandardOpenOption.WRITE, StandardOpenOption.READ);
    ch.position(6);
    ch.write(ByteBuffer.wrap(a1.encode(false)));
    ch.truncate(ch.position());
    ch.close();
    try {
        cache.checkAndStore(now, a2);
        throw new Exception();
    } catch (KrbException ke) {
        // Correct
        System.out.println(ke);
    }
}
Also used : AuthTimeWithHash(sun.security.krb5.internal.rcache.AuthTimeWithHash) SeekableByteChannel(java.nio.channels.SeekableByteChannel) ReplayCache(sun.security.krb5.internal.ReplayCache) KrbException(sun.security.krb5.KrbException) KerberosTime(sun.security.krb5.internal.KerberosTime) KrbException(sun.security.krb5.KrbException)

Example 15 with KrbException

use of sun.security.krb5.KrbException in project jdk8u_jdk by JetBrains.

the class MoreKvno method main.

public static void main(String[] args) throws Exception {
    OneKDC kdc = new OneKDC(null);
    kdc.writeJAASConf();
    // Rewrite keytab, 3 set of keys with different kvno
    KeyTab ktab = KeyTab.create(OneKDC.KTAB);
    p = new PrincipalName(OneKDC.SERVER + "@" + OneKDC.REALM, PrincipalName.KRB_NT_SRV_HST);
    ktab.addEntry(p, "pass1".toCharArray(), 1, true);
    ktab.addEntry(p, "pass3".toCharArray(), 3, true);
    ktab.addEntry(p, "pass2".toCharArray(), 2, true);
    ktab.save();
    char[] pass = "pass2".toCharArray();
    kdc.addPrincipal(OneKDC.SERVER, pass);
    go(OneKDC.SERVER, "com.sun.security.jgss.krb5.accept", pass);
    pass = "pass3".toCharArray();
    kdc.addPrincipal(OneKDC.SERVER, pass);
    // "server" initiate also, check pass2 is used at authentication
    go(OneKDC.SERVER, "server", pass);
    try {
        pass = "pass4".toCharArray();
        kdc.addPrincipal(OneKDC.SERVER, pass);
        go(OneKDC.SERVER, "com.sun.security.jgss.krb5.accept", pass);
        throw new Exception("This test should fail");
    } catch (GSSException gsse) {
    // Since 7197159, different kvno is accepted, this return code
    // will never be thrown out again.
    //KrbException ke = (KrbException)gsse.getCause();
    //if (ke.returnCode() != Krb5.KRB_AP_ERR_BADKEYVER) {
    //    throw new Exception("Not expected failure code: " +
    //            ke.returnCode());
    //}
    }
}
Also used : GSSException(org.ietf.jgss.GSSException) KeyTab(sun.security.krb5.internal.ktab.KeyTab) PrincipalName(sun.security.krb5.PrincipalName) GSSException(org.ietf.jgss.GSSException) KrbException(sun.security.krb5.KrbException)

Aggregations

KrbException (sun.security.krb5.KrbException)7 IOException (java.io.IOException)3 PrincipalName (sun.security.krb5.PrincipalName)3 KerberosString (sun.security.krb5.internal.util.KerberosString)3 PrivilegedActionException (java.security.PrivilegedActionException)2 KerberosTicket (javax.security.auth.kerberos.KerberosTicket)2 GSSException (org.ietf.jgss.GSSException)2 Config (sun.security.krb5.Config)2 CredentialsCache (sun.security.krb5.internal.ccache.CredentialsCache)2 KeyTab (sun.security.krb5.internal.ktab.KeyTab)2 AuthTimeWithHash (sun.security.krb5.internal.rcache.AuthTimeWithHash)2 DerOutputStream (sun.security.util.DerOutputStream)2 FileOutputStream (java.io.FileOutputStream)1 InvocationTargetException (java.lang.reflect.InvocationTargetException)1 SocketTimeoutException (java.net.SocketTimeoutException)1 SeekableByteChannel (java.nio.channels.SeekableByteChannel)1 NoSuchAlgorithmException (java.security.NoSuchAlgorithmException)1 Subject (javax.security.auth.Subject)1 KerberosKey (javax.security.auth.kerberos.KerberosKey)1 KerberosPrincipal (javax.security.auth.kerberos.KerberosPrincipal)1