jdk/src/java.base/share/classes/sun/security/ssl/ServerHandshaker.java
changeset 30905 bba6fefdd660
parent 30904 ec0224270f90
child 31538 0981099a3e54
equal deleted inserted replaced
30904:ec0224270f90 30905:bba6fefdd660
    36 import javax.crypto.SecretKey;
    36 import javax.crypto.SecretKey;
    37 import javax.crypto.spec.SecretKeySpec;
    37 import javax.crypto.spec.SecretKeySpec;
    38 
    38 
    39 import javax.net.ssl.*;
    39 import javax.net.ssl.*;
    40 
    40 
    41 import javax.security.auth.Subject;
       
    42 
       
    43 import sun.security.util.KeyUtil;
    41 import sun.security.util.KeyUtil;
    44 import sun.security.action.GetPropertyAction;
    42 import sun.security.action.GetPropertyAction;
    45 import sun.security.ssl.HandshakeMessage.*;
    43 import sun.security.ssl.HandshakeMessage.*;
    46 import sun.security.ssl.CipherSuite.*;
    44 import sun.security.ssl.CipherSuite.*;
    47 import sun.security.ssl.SignatureAndHashAlgorithm.*;
    45 import sun.security.ssl.SignatureAndHashAlgorithm.*;
   234                             protocolVersion, clientRequestedVersion,
   232                             protocolVersion, clientRequestedVersion,
   235                             sslContext.getSecureRandom(), input,
   233                             sslContext.getSecureRandom(), input,
   236                             message_len, privateKey);
   234                             message_len, privateKey);
   237                     handshakeState.update(pms, resumingSession);
   235                     handshakeState.update(pms, resumingSession);
   238                     preMasterSecret = this.clientKeyExchange(pms);
   236                     preMasterSecret = this.clientKeyExchange(pms);
   239                     break;
       
   240                 case K_KRB5:
       
   241                 case K_KRB5_EXPORT:
       
   242                     KerberosClientKeyExchange kke =
       
   243                         new KerberosClientKeyExchange(protocolVersion,
       
   244                             clientRequestedVersion,
       
   245                             sslContext.getSecureRandom(),
       
   246                             input,
       
   247                             this.getAccSE(),
       
   248                             serviceCreds);
       
   249                     handshakeState.update(kke, resumingSession);
       
   250                     preMasterSecret = this.clientKeyExchange(kke);
       
   251                     break;
   237                     break;
   252                 case K_DHE_RSA:
   238                 case K_DHE_RSA:
   253                 case K_DHE_DSS:
   239                 case K_DHE_DSS:
   254                 case K_DH_ANON:
   240                 case K_DH_ANON:
   255                     /*
   241                     /*
   271                                     new ECDHClientKeyExchange(input);
   257                                     new ECDHClientKeyExchange(input);
   272                     handshakeState.update(ecdhcke, resumingSession);
   258                     handshakeState.update(ecdhcke, resumingSession);
   273                     preMasterSecret = this.clientKeyExchange(ecdhcke);
   259                     preMasterSecret = this.clientKeyExchange(ecdhcke);
   274                     break;
   260                     break;
   275                 default:
   261                 default:
   276                     throw new SSLProtocolException
   262                     ClientKeyExchangeService p =
   277                         ("Unrecognized key exchange: " + keyExchange);
   263                             ClientKeyExchangeService.find(keyExchange.name);
       
   264                     if (p == null) {
       
   265                         throw new SSLProtocolException
       
   266                                 ("Unrecognized key exchange: " + keyExchange);
       
   267                     }
       
   268                     byte[] encodedTicket = input.getBytes16();
       
   269                     input.getBytes16();
       
   270                     byte[] secret = input.getBytes16();
       
   271                     ClientKeyExchange cke = p.createServerExchange(protocolVersion,
       
   272                             clientRequestedVersion,
       
   273                             sslContext.getSecureRandom(),
       
   274                             encodedTicket,
       
   275                             secret,
       
   276                             this.getAccSE(), serviceCreds);
       
   277                     handshakeState.update(cke, resumingSession);
       
   278                     preMasterSecret = this.clientKeyExchange(cke);
       
   279                     break;
   278                 }
   280                 }
   279 
   281 
   280                 //
   282                 //
   281                 // All keys are calculated from the premaster secret
   283                 // All keys are calculated from the premaster secret
   282                 // and the exchanged nonces in the same way.
   284                 // and the exchanged nonces in the same way.
   622                 }
   624                 }
   623 
   625 
   624                 // validate subject identity
   626                 // validate subject identity
   625                 if (resumingSession) {
   627                 if (resumingSession) {
   626                     CipherSuite suite = previous.getSuite();
   628                     CipherSuite suite = previous.getSuite();
   627                     if (suite.keyExchange == K_KRB5 ||
   629                     ClientKeyExchangeService p =
   628                         suite.keyExchange == K_KRB5_EXPORT) {
   630                             ClientKeyExchangeService.find(suite.keyExchange.name);
       
   631                     if (p != null) {
   629                         Principal localPrincipal = previous.getLocalPrincipal();
   632                         Principal localPrincipal = previous.getLocalPrincipal();
   630 
   633 
   631                         Subject subject = null;
   634                         if (p.isRelated(
   632                         try {
   635                                 false, getAccSE(), localPrincipal)) {
   633                             subject = AccessController.doPrivileged(
   636                             if (debug != null && Debug.isOn("session"))
   634                                 new PrivilegedExceptionAction<Subject>() {
   637                                 System.out.println("Subject can" +
   635                                 @Override
   638                                         " provide creds for princ");
   636                                 public Subject run() throws Exception {
       
   637                                     return
       
   638                                         Krb5Helper.getServerSubject(getAccSE());
       
   639                             }});
       
   640                         } catch (PrivilegedActionException e) {
       
   641                             subject = null;
       
   642                             if (debug != null && Debug.isOn("session")) {
       
   643                                 System.out.println("Attempt to obtain" +
       
   644                                                 " subject failed!");
       
   645                             }
       
   646                         }
       
   647 
       
   648                         if (subject != null) {
       
   649                             // Eliminate dependency on KerberosPrincipal
       
   650                             if (Krb5Helper.isRelated(subject, localPrincipal)) {
       
   651                                 if (debug != null && Debug.isOn("session"))
       
   652                                     System.out.println("Subject can" +
       
   653                                             " provide creds for princ");
       
   654                             } else {
       
   655                                 resumingSession = false;
       
   656                                 if (debug != null && Debug.isOn("session"))
       
   657                                     System.out.println("Subject cannot" +
       
   658                                             " provide creds for princ");
       
   659                             }
       
   660                         } else {
   639                         } else {
   661                             resumingSession = false;
   640                             resumingSession = false;
   662                             if (debug != null && Debug.isOn("session"))
   641                             if (debug != null && Debug.isOn("session"))
   663                                 System.out.println("Kerberos credentials are" +
   642                                 System.out.println("Subject cannot" +
   664                                     " not present in the current Subject;" +
   643                                         " provide creds for princ");
   665                                     " check if " +
       
   666                                     " javax.security.auth.useSubjectAsCreds" +
       
   667                                     " system property has been set to false");
       
   668                         }
   644                         }
   669                     }
   645                     }
   670                 }
   646                 }
   671 
   647 
   672                 if (resumingSession) {
   648                 if (resumingSession) {
   869          * NOTE:  while an "anonymous RSA" mode is explicitly allowed by
   845          * NOTE:  while an "anonymous RSA" mode is explicitly allowed by
   870          * the protocol, we can't support it since all of the SSL flavors
   846          * the protocol, we can't support it since all of the SSL flavors
   871          * defined in the protocol spec are explicitly stated to require
   847          * defined in the protocol spec are explicitly stated to require
   872          * using RSA certificates.
   848          * using RSA certificates.
   873          */
   849          */
   874         if (keyExchange == K_KRB5 || keyExchange == K_KRB5_EXPORT) {
   850         if (ClientKeyExchangeService.find(cipherSuite.keyExchange.name) != null) {
   875             // Server certificates are omitted for Kerberos ciphers
   851             // No external key exchange provider needs a cert now.
   876 
       
   877         } else if ((keyExchange != K_DH_ANON) && (keyExchange != K_ECDH_ANON)) {
   852         } else if ((keyExchange != K_DH_ANON) && (keyExchange != K_ECDH_ANON)) {
   878             if (certs == null) {
   853             if (certs == null) {
   879                 throw new RuntimeException("no certificates");
   854                 throw new RuntimeException("no certificates");
   880             }
   855             }
   881 
   856 
   913          */
   888          */
   914 
   889 
   915         ServerKeyExchange m3;
   890         ServerKeyExchange m3;
   916         switch (keyExchange) {
   891         switch (keyExchange) {
   917         case K_RSA:
   892         case K_RSA:
   918         case K_KRB5:
   893             // no server key exchange for RSA ciphersuites
   919         case K_KRB5_EXPORT:
       
   920             // no server key exchange for RSA or KRB5 ciphersuites
       
   921             m3 = null;
   894             m3 = null;
   922             break;
   895             break;
   923         case K_RSA_EXPORT:
   896         case K_RSA_EXPORT:
   924             if (JsseJce.getRSAKeyLength(certs[0].getPublicKey()) > 512) {
   897             if (JsseJce.getRSAKeyLength(certs[0].getPublicKey()) > 512) {
   925                 try {
   898                 try {
   978         case K_ECDH_ECDSA:
   951         case K_ECDH_ECDSA:
   979             // ServerKeyExchange not used for fixed ECDH
   952             // ServerKeyExchange not used for fixed ECDH
   980             m3 = null;
   953             m3 = null;
   981             break;
   954             break;
   982         default:
   955         default:
       
   956             ClientKeyExchangeService p =
       
   957                     ClientKeyExchangeService.find(keyExchange.name);
       
   958             if (p != null) {
       
   959                 // No external key exchange provider needs a cert now.
       
   960                 m3 = null;
       
   961                 break;
       
   962             }
   983             throw new RuntimeException("internal error: " + keyExchange);
   963             throw new RuntimeException("internal error: " + keyExchange);
   984         }
   964         }
   985         if (m3 != null) {
   965         if (m3 != null) {
   986             if (debug != null && Debug.isOn("handshake")) {
   966             if (debug != null && Debug.isOn("handshake")) {
   987                 m3.print(System.out);
   967                 m3.print(System.out);
   998         // algorithms.
   978         // algorithms.
   999         //
   979         //
  1000         // Needed only if server requires client to authenticate self.
   980         // Needed only if server requires client to authenticate self.
  1001         // Illegal for anonymous flavors, so we need to check that.
   981         // Illegal for anonymous flavors, so we need to check that.
  1002         //
   982         //
  1003         // CertificateRequest is omitted for Kerberos ciphers
   983         // No external key exchange provider needs a cert now.
  1004         if (doClientAuth != ClientAuthType.CLIENT_AUTH_NONE &&
   984         if (doClientAuth != ClientAuthType.CLIENT_AUTH_NONE &&
  1005                 keyExchange != K_DH_ANON && keyExchange != K_ECDH_ANON &&
   985                 keyExchange != K_DH_ANON && keyExchange != K_ECDH_ANON &&
  1006                 keyExchange != K_KRB5 && keyExchange != K_KRB5_EXPORT) {
   986                 ClientKeyExchangeService.find(keyExchange.name) == null) {
  1007 
   987 
  1008             CertificateRequest m4;
   988             CertificateRequest m4;
  1009             X509Certificate caCerts[];
   989             X509Certificate caCerts[];
  1010 
   990 
  1011             Collection<SignatureAndHashAlgorithm> localSignAlgs = null;
   991             Collection<SignatureAndHashAlgorithm> localSignAlgs = null;
  1311             if (setupPrivateKeyAndChain("EC_EC") == false) {
  1291             if (setupPrivateKeyAndChain("EC_EC") == false) {
  1312                 return false;
  1292                 return false;
  1313             }
  1293             }
  1314             setupStaticECDHKeys();
  1294             setupStaticECDHKeys();
  1315             break;
  1295             break;
  1316         case K_KRB5:
       
  1317         case K_KRB5_EXPORT:
       
  1318             // need Kerberos Key
       
  1319             if (!setupKerberosKeys()) {
       
  1320                 return false;
       
  1321             }
       
  1322             break;
       
  1323         case K_DH_ANON:
  1296         case K_DH_ANON:
  1324             // no certs needed for anonymous
  1297             // no certs needed for anonymous
  1325             setupEphemeralDHKeys(suite.exportable, null);
  1298             setupEphemeralDHKeys(suite.exportable, null);
  1326             break;
  1299             break;
  1327         case K_ECDH_ANON:
  1300         case K_ECDH_ANON:
  1329             if (setupEphemeralECDHKeys() == false) {
  1302             if (setupEphemeralECDHKeys() == false) {
  1330                 return false;
  1303                 return false;
  1331             }
  1304             }
  1332             break;
  1305             break;
  1333         default:
  1306         default:
  1334             // internal error, unknown key exchange
  1307             ClientKeyExchangeService p =
  1335             throw new RuntimeException("Unrecognized cipherSuite: " + suite);
  1308                     ClientKeyExchangeService.find(keyExchange.name);
       
  1309             if (p == null) {
       
  1310                 // internal error, unknown key exchange
       
  1311                 throw new RuntimeException("Unrecognized cipherSuite: " + suite);
       
  1312             }
       
  1313             // need service creds
       
  1314             if (serviceCreds == null) {
       
  1315                 AccessControlContext acc = getAccSE();
       
  1316                 serviceCreds = p.getServiceCreds(acc);
       
  1317                 if (serviceCreds != null) {
       
  1318                     if (debug != null && Debug.isOn("handshake")) {
       
  1319                         System.out.println("Using serviceCreds");
       
  1320                     }
       
  1321                 }
       
  1322                 if (serviceCreds == null) {
       
  1323                     return false;
       
  1324                 }
       
  1325             }
       
  1326             break;
  1336         }
  1327         }
  1337         setCipherSuite(suite);
  1328         setCipherSuite(suite);
  1338 
  1329 
  1339         // set the peer implicit supported signature algorithms
  1330         // set the peer implicit supported signature algorithms
  1340         if (protocolVersion.useTLS12PlusSpec()) {
  1331         if (protocolVersion.useTLS12PlusSpec()) {
  1520         this.privateKey = tempPrivateKey;
  1511         this.privateKey = tempPrivateKey;
  1521         this.certs = tempCerts;
  1512         this.certs = tempCerts;
  1522         return true;
  1513         return true;
  1523     }
  1514     }
  1524 
  1515 
  1525     /**
       
  1526      * Retrieve the Kerberos key for the specified server principal
       
  1527      * from the JAAS configuration file.
       
  1528      *
       
  1529      * @return true if successful, false if not available or invalid
       
  1530      */
       
  1531     private boolean setupKerberosKeys() {
       
  1532         if (serviceCreds != null) {
       
  1533             return true;
       
  1534         }
       
  1535         try {
       
  1536             final AccessControlContext acc = getAccSE();
       
  1537             serviceCreds = AccessController.doPrivileged(
       
  1538                 // Eliminate dependency on KerberosKey
       
  1539                 new PrivilegedExceptionAction<Object>() {
       
  1540                 @Override
       
  1541                 public Object run() throws Exception {
       
  1542                     // get kerberos key for the default principal
       
  1543                     return Krb5Helper.getServiceCreds(acc);
       
  1544                         }});
       
  1545 
       
  1546             // check permission to access and use the secret key of the
       
  1547             // Kerberized "host" service
       
  1548             if (serviceCreds != null) {
       
  1549                 if (debug != null && Debug.isOn("handshake")) {
       
  1550                     System.out.println("Using Kerberos creds");
       
  1551                 }
       
  1552                 String serverPrincipal =
       
  1553                         Krb5Helper.getServerPrincipalName(serviceCreds);
       
  1554                 if (serverPrincipal != null) {
       
  1555                     // When service is bound, we check ASAP. Otherwise,
       
  1556                     // will check after client request is received
       
  1557                     // in Kerberos ClientKeyExchange
       
  1558                     SecurityManager sm = System.getSecurityManager();
       
  1559                     try {
       
  1560                         if (sm != null) {
       
  1561                             // Eliminate dependency on ServicePermission
       
  1562                             sm.checkPermission(Krb5Helper.getServicePermission(
       
  1563                                     serverPrincipal, "accept"), acc);
       
  1564                         }
       
  1565                     } catch (SecurityException se) {
       
  1566                         serviceCreds = null;
       
  1567                         // Do not destroy keys. Will affect Subject
       
  1568                         if (debug != null && Debug.isOn("handshake")) {
       
  1569                             System.out.println("Permission to access Kerberos"
       
  1570                                     + " secret key denied");
       
  1571                         }
       
  1572                         return false;
       
  1573                     }
       
  1574                 }
       
  1575             }
       
  1576             return serviceCreds != null;
       
  1577         } catch (PrivilegedActionException e) {
       
  1578             // Likely exception here is LoginExceptin
       
  1579             if (debug != null && Debug.isOn("handshake")) {
       
  1580                 System.out.println("Attempt to obtain Kerberos key failed: "
       
  1581                                 + e.toString());
       
  1582             }
       
  1583             return false;
       
  1584         }
       
  1585     }
       
  1586 
       
  1587     /*
  1516     /*
  1588      * For Kerberos ciphers, the premaster secret is encrypted using
  1517      * Returns premaster secret for external key exchange services.
  1589      * the session key. See RFC 2712.
  1518      */
  1590      */
  1519     private SecretKey clientKeyExchange(ClientKeyExchange mesg)
  1591     private SecretKey clientKeyExchange(KerberosClientKeyExchange mesg)
       
  1592         throws IOException {
  1520         throws IOException {
  1593 
  1521 
  1594         if (debug != null && Debug.isOn("handshake")) {
  1522         if (debug != null && Debug.isOn("handshake")) {
  1595             mesg.print(System.out);
  1523             mesg.print(System.out);
  1596         }
  1524         }
  1597 
  1525 
  1598         // Record the principals involved in exchange
  1526         // Record the principals involved in exchange
  1599         session.setPeerPrincipal(mesg.getPeerPrincipal());
  1527         session.setPeerPrincipal(mesg.getPeerPrincipal());
  1600         session.setLocalPrincipal(mesg.getLocalPrincipal());
  1528         session.setLocalPrincipal(mesg.getLocalPrincipal());
  1601 
  1529 
  1602         byte[] b = mesg.getUnencryptedPreMasterSecret();
  1530         return mesg.clientKeyExchange();
  1603         return new SecretKeySpec(b, "TlsPremasterSecret");
       
  1604     }
  1531     }
  1605 
  1532 
  1606     /*
  1533     /*
  1607      * Diffie Hellman key exchange is used when the server presented
  1534      * Diffie Hellman key exchange is used when the server presented
  1608      * D-H parameters in its certificate (signed using RSA or DSS/DSA),
  1535      * D-H parameters in its certificate (signed using RSA or DSS/DSA),
  1703          * Verify if client did send the certificate when client
  1630          * Verify if client did send the certificate when client
  1704          * authentication was required, otherwise server should not proceed
  1631          * authentication was required, otherwise server should not proceed
  1705          */
  1632          */
  1706         if (doClientAuth == ClientAuthType.CLIENT_AUTH_REQUIRED) {
  1633         if (doClientAuth == ClientAuthType.CLIENT_AUTH_REQUIRED) {
  1707            // get X500Principal of the end-entity certificate for X509-based
  1634            // get X500Principal of the end-entity certificate for X509-based
  1708            // ciphersuites, or Kerberos principal for Kerberos ciphersuites
  1635            // ciphersuites, or Kerberos principal for Kerberos ciphersuites, etc
  1709            session.getPeerPrincipal();
  1636            session.getPeerPrincipal();
  1710         }
  1637         }
  1711 
  1638 
  1712         /*
  1639         /*
  1713          * Verify if client did send clientCertificateVerify message following
  1640          * Verify if client did send clientCertificateVerify message following