24 */
25
26 package sun.security.ssl;
27
28 import java.io.*;
29 import java.math.BigInteger;
30 import java.security.*;
31 import java.security.interfaces.*;
32 import java.security.spec.*;
33 import java.security.cert.*;
34 import java.security.cert.Certificate;
35 import java.util.*;
36 import java.util.concurrent.ConcurrentHashMap;
37
38 import java.lang.reflect.*;
39
40 import javax.security.auth.x500.X500Principal;
41
42 import javax.crypto.KeyGenerator;
43 import javax.crypto.SecretKey;
44
45 import javax.net.ssl.*;
46
47 import sun.security.internal.spec.TlsPrfParameterSpec;
48 import sun.security.ssl.CipherSuite.*;
49 import static sun.security.ssl.CipherSuite.PRF.*;
50
51 /**
52 * Many data structures are involved in the handshake messages. These
53 * classes are used as structures, with public data members. They are
54 * not visible outside the SSL package.
55 *
56 * Handshake messages all have a common header format, and they are all
57 * encoded in a "handshake data" SSL record substream. The base class
58 * here (HandshakeMessage) provides a common framework and records the
59 * SSL record type of the particular handshake message.
60 *
61 * This file contains subclasses for all the basic handshake messages.
62 * All handshake messages know how to encode and decode themselves on
63 * SSL streams; this facilitates using the same code on SSL client and
64 * server sides, although they don't send and receive the same messages.
65 *
66 * Messages also know how to print themselves, which is quite handy
67 * for debugging. They always identify their type, and can optionally
68 * dump all of their content.
69 *
685 private byte dh_p []; // 1 to 2^16 - 1 bytes
686 private byte dh_g []; // 1 to 2^16 - 1 bytes
687 private byte dh_Ys []; // 1 to 2^16 - 1 bytes
688
689 private byte signature [];
690
691 // protocol version being established using this ServerKeyExchange message
692 ProtocolVersion protocolVersion;
693
694 // the preferable signature algorithm used by this ServerKeyExchange message
695 private SignatureAndHashAlgorithm preferableSignatureAlgorithm;
696
697 /*
698 * Construct from initialized DH key object, for DH_anon
699 * key exchange.
700 */
701 DH_ServerKeyExchange(DHCrypt obj, ProtocolVersion protocolVersion) {
702 this.protocolVersion = protocolVersion;
703 this.preferableSignatureAlgorithm = null;
704
705 setValues(obj);
706 signature = null;
707 }
708
709 /*
710 * Construct from initialized DH key object and the key associated
711 * with the cert chain which was sent ... for DHE_DSS and DHE_RSA
712 * key exchange. (Constructor called by server.)
713 */
714 DH_ServerKeyExchange(DHCrypt obj, PrivateKey key, byte clntNonce[],
715 byte svrNonce[], SecureRandom sr,
716 SignatureAndHashAlgorithm signAlgorithm,
717 ProtocolVersion protocolVersion) throws GeneralSecurityException {
718
719 this.protocolVersion = protocolVersion;
720
721 setValues(obj);
722
723 Signature sig;
724 if (protocolVersion.v >= ProtocolVersion.TLS12.v) {
725 this.preferableSignatureAlgorithm = signAlgorithm;
726 sig = JsseJce.getSignature(signAlgorithm.getAlgorithmName());
727 } else {
728 this.preferableSignatureAlgorithm = null;
729 if (key.getAlgorithm().equals("DSA")) {
730 sig = JsseJce.getSignature(JsseJce.SIGNATURE_DSA);
731 } else {
732 sig = RSASignature.getInstance();
733 }
734 }
735
736 sig.initSign(key, sr);
737 updateSignature(sig, clntNonce, svrNonce);
738 signature = sig.sign();
739 }
740
741 /*
742 * Construct a DH_ServerKeyExchange message from an input
743 * stream, as if sent from server to client for use with
744 * DH_anon key exchange
745 */
746 DH_ServerKeyExchange(HandshakeInStream input,
747 ProtocolVersion protocolVersion) throws IOException {
748
749 this.protocolVersion = protocolVersion;
750 this.preferableSignatureAlgorithm = null;
751
752 dh_p = input.getBytes16();
753 dh_g = input.getBytes16();
754 dh_Ys = input.getBytes16();
755 signature = null;
756 }
757
758 /*
759 * Construct a DH_ServerKeyExchange message from an input stream
760 * and a certificate, as if sent from server to client for use with
761 * DHE_DSS or DHE_RSA key exchange. (Called by client.)
762 */
763 DH_ServerKeyExchange(HandshakeInStream input, PublicKey publicKey,
764 byte clntNonce[], byte svrNonce[], int messageSize,
765 Collection<SignatureAndHashAlgorithm> localSupportedSignAlgs,
766 ProtocolVersion protocolVersion)
767 throws IOException, GeneralSecurityException {
768
769 this.protocolVersion = protocolVersion;
770
771 // read params: ServerDHParams
772 dh_p = input.getBytes16();
773 dh_g = input.getBytes16();
774 dh_Ys = input.getBytes16();
775
776 // read the signature and hash algorithm
777 if (protocolVersion.v >= ProtocolVersion.TLS12.v) {
778 int hash = input.getInt8(); // hash algorithm
779 int signature = input.getInt8(); // signature algorithm
780
781 preferableSignatureAlgorithm =
782 SignatureAndHashAlgorithm.valueOf(hash, signature, 0);
783
784 // Is it a local supported signature algorithm?
785 if (!localSupportedSignAlgs.contains(
786 preferableSignatureAlgorithm)) {
787 throw new SSLHandshakeException(
788 "Unsupported SignatureAndHashAlgorithm in " +
789 "ServerKeyExchange message");
790 }
791 } else {
792 this.preferableSignatureAlgorithm = null;
793 }
794
|
24 */
25
26 package sun.security.ssl;
27
28 import java.io.*;
29 import java.math.BigInteger;
30 import java.security.*;
31 import java.security.interfaces.*;
32 import java.security.spec.*;
33 import java.security.cert.*;
34 import java.security.cert.Certificate;
35 import java.util.*;
36 import java.util.concurrent.ConcurrentHashMap;
37
38 import java.lang.reflect.*;
39
40 import javax.security.auth.x500.X500Principal;
41
42 import javax.crypto.KeyGenerator;
43 import javax.crypto.SecretKey;
44 import javax.crypto.spec.DHPublicKeySpec;
45
46 import javax.net.ssl.*;
47
48 import sun.security.internal.spec.TlsPrfParameterSpec;
49 import sun.security.ssl.CipherSuite.*;
50 import static sun.security.ssl.CipherSuite.PRF.*;
51 import sun.security.util.KeyUtil;
52
53 /**
54 * Many data structures are involved in the handshake messages. These
55 * classes are used as structures, with public data members. They are
56 * not visible outside the SSL package.
57 *
58 * Handshake messages all have a common header format, and they are all
59 * encoded in a "handshake data" SSL record substream. The base class
60 * here (HandshakeMessage) provides a common framework and records the
61 * SSL record type of the particular handshake message.
62 *
63 * This file contains subclasses for all the basic handshake messages.
64 * All handshake messages know how to encode and decode themselves on
65 * SSL streams; this facilitates using the same code on SSL client and
66 * server sides, although they don't send and receive the same messages.
67 *
68 * Messages also know how to print themselves, which is quite handy
69 * for debugging. They always identify their type, and can optionally
70 * dump all of their content.
71 *
687 private byte dh_p []; // 1 to 2^16 - 1 bytes
688 private byte dh_g []; // 1 to 2^16 - 1 bytes
689 private byte dh_Ys []; // 1 to 2^16 - 1 bytes
690
691 private byte signature [];
692
693 // protocol version being established using this ServerKeyExchange message
694 ProtocolVersion protocolVersion;
695
696 // the preferable signature algorithm used by this ServerKeyExchange message
697 private SignatureAndHashAlgorithm preferableSignatureAlgorithm;
698
699 /*
700 * Construct from initialized DH key object, for DH_anon
701 * key exchange.
702 */
703 DH_ServerKeyExchange(DHCrypt obj, ProtocolVersion protocolVersion) {
704 this.protocolVersion = protocolVersion;
705 this.preferableSignatureAlgorithm = null;
706
707 // The DH key has been validated in the constructor of DHCrypt.
708 setValues(obj);
709 signature = null;
710 }
711
712 /*
713 * Construct from initialized DH key object and the key associated
714 * with the cert chain which was sent ... for DHE_DSS and DHE_RSA
715 * key exchange. (Constructor called by server.)
716 */
717 DH_ServerKeyExchange(DHCrypt obj, PrivateKey key, byte clntNonce[],
718 byte svrNonce[], SecureRandom sr,
719 SignatureAndHashAlgorithm signAlgorithm,
720 ProtocolVersion protocolVersion) throws GeneralSecurityException {
721
722 this.protocolVersion = protocolVersion;
723
724 // The DH key has been validated in the constructor of DHCrypt.
725 setValues(obj);
726
727 Signature sig;
728 if (protocolVersion.v >= ProtocolVersion.TLS12.v) {
729 this.preferableSignatureAlgorithm = signAlgorithm;
730 sig = JsseJce.getSignature(signAlgorithm.getAlgorithmName());
731 } else {
732 this.preferableSignatureAlgorithm = null;
733 if (key.getAlgorithm().equals("DSA")) {
734 sig = JsseJce.getSignature(JsseJce.SIGNATURE_DSA);
735 } else {
736 sig = RSASignature.getInstance();
737 }
738 }
739
740 sig.initSign(key, sr);
741 updateSignature(sig, clntNonce, svrNonce);
742 signature = sig.sign();
743 }
744
745 /*
746 * Construct a DH_ServerKeyExchange message from an input
747 * stream, as if sent from server to client for use with
748 * DH_anon key exchange
749 */
750 DH_ServerKeyExchange(HandshakeInStream input,
751 ProtocolVersion protocolVersion)
752 throws IOException, GeneralSecurityException {
753
754 this.protocolVersion = protocolVersion;
755 this.preferableSignatureAlgorithm = null;
756
757 dh_p = input.getBytes16();
758 dh_g = input.getBytes16();
759 dh_Ys = input.getBytes16();
760 KeyUtil.validate(new DHPublicKeySpec(new BigInteger(1, dh_Ys),
761 new BigInteger(1, dh_p),
762 new BigInteger(1, dh_g)));
763
764 signature = null;
765 }
766
767 /*
768 * Construct a DH_ServerKeyExchange message from an input stream
769 * and a certificate, as if sent from server to client for use with
770 * DHE_DSS or DHE_RSA key exchange. (Called by client.)
771 */
772 DH_ServerKeyExchange(HandshakeInStream input, PublicKey publicKey,
773 byte clntNonce[], byte svrNonce[], int messageSize,
774 Collection<SignatureAndHashAlgorithm> localSupportedSignAlgs,
775 ProtocolVersion protocolVersion)
776 throws IOException, GeneralSecurityException {
777
778 this.protocolVersion = protocolVersion;
779
780 // read params: ServerDHParams
781 dh_p = input.getBytes16();
782 dh_g = input.getBytes16();
783 dh_Ys = input.getBytes16();
784 KeyUtil.validate(new DHPublicKeySpec(new BigInteger(1, dh_Ys),
785 new BigInteger(1, dh_p),
786 new BigInteger(1, dh_g)));
787
788 // read the signature and hash algorithm
789 if (protocolVersion.v >= ProtocolVersion.TLS12.v) {
790 int hash = input.getInt8(); // hash algorithm
791 int signature = input.getInt8(); // signature algorithm
792
793 preferableSignatureAlgorithm =
794 SignatureAndHashAlgorithm.valueOf(hash, signature, 0);
795
796 // Is it a local supported signature algorithm?
797 if (!localSupportedSignAlgs.contains(
798 preferableSignatureAlgorithm)) {
799 throw new SSLHandshakeException(
800 "Unsupported SignatureAndHashAlgorithm in " +
801 "ServerKeyExchange message");
802 }
803 } else {
804 this.preferableSignatureAlgorithm = null;
805 }
806
|