866 lines · 28.6 KB · Java
RawDownload
        int k = curveIds.length << 1;        s.putInt16(k + 2);        s.putInt16(k);        for (int curveId : curveIds) {            s.putInt16(curveId);        }    }     public String toString() {        StringBuilder sb = new StringBuilder();        sb.append("Extension " + type + ", curve names: {");        boolean first = true;        for (int curveId : curveIds) {            if (first) {                first = false;            } else {                sb.append(", ");            }            // first check if it is a known named curve, then try other cases.            String oid = getCurveOid(curveId);            if (oid != null) {                ECParameterSpec spec = JsseJce.getECParameterSpec(oid);                // this toString() output will look nice for the current                // implementation of the ECParameterSpec class in the Sun                // provider, but may not look good for other implementations.                if (spec != null) {                    sb.append(spec.toString().split(" ")[0]);                } else {                    sb.append(oid);                }            } else if (curveId == ARBITRARY_PRIME) {                sb.append("arbitrary_explicit_prime_curves");            } else if (curveId == ARBITRARY_CHAR2) {                sb.append("arbitrary_explicit_char2_curves");            } else {                sb.append("unknown curve " + curveId);            }        }        sb.append("}");        return sb.toString();    }     // Test whether we support the curve with the given index.    static boolean isSupported(int index) {        if ((index <= 0) || (index >= NAMED_CURVE_OID_TABLE.length)) {            return false;        }        if (fips == false) {            // in non-FIPS mode, we support all valid indices            return true;        }        return DEFAULT.contains(index);    }     static int getCurveIndex(ECParameterSpec params) {        String oid = JsseJce.getNamedCurveOid(params);        if (oid == null) {            return -1;        }        Integer n = curveIndices.get(oid);        return (n == null) ? -1 : n;    }     static String getCurveOid(int index) {        if ((index > 0) && (index < NAMED_CURVE_OID_TABLE.length)) {            return NAMED_CURVE_OID_TABLE[index];        }        return null;    }     private final static int ARBITRARY_PRIME = 0xff01;    private final static int ARBITRARY_CHAR2 = 0xff02;     // See sun.security.ec.NamedCurve for the OIDs    private final static String[] NAMED_CURVE_OID_TABLE = new String[] {        null,                   //  (0) unused        "1.3.132.0.1",          //  (1) sect163k1, NIST K-163        "1.3.132.0.2",          //  (2) sect163r1        "1.3.132.0.15",         //  (3) sect163r2, NIST B-163        "1.3.132.0.24",         //  (4) sect193r1        "1.3.132.0.25",         //  (5) sect193r2        "1.3.132.0.26",         //  (6) sect233k1, NIST K-233        "1.3.132.0.27",         //  (7) sect233r1, NIST B-233        "1.3.132.0.3",          //  (8) sect239k1        "1.3.132.0.16",         //  (9) sect283k1, NIST K-283        "1.3.132.0.17",         // (10) sect283r1, NIST B-283        "1.3.132.0.36",         // (11) sect409k1, NIST K-409        "1.3.132.0.37",         // (12) sect409r1, NIST B-409        "1.3.132.0.38",         // (13) sect571k1, NIST K-571        "1.3.132.0.39",         // (14) sect571r1, NIST B-571        "1.3.132.0.9",          // (15) secp160k1        "1.3.132.0.8",          // (16) secp160r1        "1.3.132.0.30",         // (17) secp160r2        "1.3.132.0.31",         // (18) secp192k1        "1.2.840.10045.3.1.1",  // (19) secp192r1, NIST P-192        "1.3.132.0.32",         // (20) secp224k1        "1.3.132.0.33",         // (21) secp224r1, NIST P-224        "1.3.132.0.10",         // (22) secp256k1        "1.2.840.10045.3.1.7",  // (23) secp256r1, NIST P-256        "1.3.132.0.34",         // (24) secp384r1, NIST P-384        "1.3.132.0.35",         // (25) secp521r1, NIST P-521    };     private final static Map<String,Integer> curveIndices;     static {        curveIndices = new HashMap<String,Integer>();        for (int i = 1; i < NAMED_CURVE_OID_TABLE.length; i++) {            curveIndices.put(NAMED_CURVE_OID_TABLE[i], i);        }    } } final class SupportedEllipticPointFormatsExtension extends HelloExtension {     final static int FMT_UNCOMPRESSED = 0;    final static int FMT_ANSIX962_COMPRESSED_PRIME = 1;    final static int FMT_ANSIX962_COMPRESSED_CHAR2 = 2;     static final HelloExtension DEFAULT =        new SupportedEllipticPointFormatsExtension(            new byte[] {FMT_UNCOMPRESSED});     private final byte[] formats;     private SupportedEllipticPointFormatsExtension(byte[] formats) {        super(ExtensionType.EXT_EC_POINT_FORMATS);        this.formats = formats;    }     SupportedEllipticPointFormatsExtension(HandshakeInStream s, int len)            throws IOException {        super(ExtensionType.EXT_EC_POINT_FORMATS);        formats = s.getBytes8();        // RFC 4492 says uncompressed points must always be supported.        // Check just to make sure.        boolean uncompressed = false;        for (int format : formats) {            if (format == FMT_UNCOMPRESSED) {                uncompressed = true;                break;            }        }        if (uncompressed == false) {            throw new SSLProtocolException                ("Peer does not support uncompressed points");        }    }     int length() {        return 5 + formats.length;    }     void send(HandshakeOutStream s) throws IOException {        s.putInt16(type.id);        s.putInt16(formats.length + 1);        s.putBytes8(formats);    }     private static String toString(byte format) {        int f = format & 0xff;        switch (f) {        case FMT_UNCOMPRESSED:            return "uncompressed";        case FMT_ANSIX962_COMPRESSED_PRIME:            return "ansiX962_compressed_prime";        case FMT_ANSIX962_COMPRESSED_CHAR2:            return "ansiX962_compressed_char2";        default:            return "unknown-" + f;        }    }     public String toString() {        List<String> list = new ArrayList<>();        for (byte format : formats) {            list.add(toString(format));        }        return "Extension " + type + ", formats: " + list;    }} /* * For secure renegotiation, RFC5746 defines a new TLS extension, * "renegotiation_info" (with extension type 0xff01), which contains a * cryptographic binding to the enclosing TLS connection (if any) for * which the renegotiation is being performed.  The "extension data" * field of this extension contains a "RenegotiationInfo" structure: * *      struct { *          opaque renegotiated_connection<0..255>; *      } RenegotiationInfo; */final class RenegotiationInfoExtension extends HelloExtension {    private final byte[] renegotiated_connection;     RenegotiationInfoExtension(byte[] clientVerifyData,                byte[] serverVerifyData) {        super(ExtensionType.EXT_RENEGOTIATION_INFO);         if (clientVerifyData.length != 0) {            renegotiated_connection =                    new byte[clientVerifyData.length + serverVerifyData.length];            System.arraycopy(clientVerifyData, 0, renegotiated_connection,                    0, clientVerifyData.length);             if (serverVerifyData.length != 0) {                System.arraycopy(serverVerifyData, 0, renegotiated_connection,                        clientVerifyData.length, serverVerifyData.length);            }        } else {            // ignore both the client and server verify data.            renegotiated_connection = new byte[0];        }    }     RenegotiationInfoExtension(HandshakeInStream s, int len)                throws IOException {        super(ExtensionType.EXT_RENEGOTIATION_INFO);         // check the extension length        if (len < 1) {            throw new SSLProtocolException("Invalid " + type + " extension");        }         int renegoInfoDataLen = s.getInt8();        if (renegoInfoDataLen + 1 != len) {  // + 1 = the byte we just read            throw new SSLProtocolException("Invalid " + type + " extension");        }         renegotiated_connection = new byte[renegoInfoDataLen];        if (renegoInfoDataLen != 0) {            s.read(renegotiated_connection, 0, renegoInfoDataLen);        }    }      // Length of the encoded extension, including the type and length fields    int length() {        return 5 + renegotiated_connection.length;    }     void send(HandshakeOutStream s) throws IOException {        s.putInt16(type.id);        s.putInt16(renegotiated_connection.length + 1);        s.putBytes8(renegotiated_connection);    }     boolean isEmpty() {        return renegotiated_connection.length == 0;    }     byte[] getRenegotiatedConnection() {        return renegotiated_connection;    }     public String toString() {        return "Extension " + type + ", renegotiated_connection: " +                    (renegotiated_connection.length == 0 ? "<empty>" :                    Debug.toString(renegotiated_connection));    } } /* * [RFC5246] The client uses the "signature_algorithms" extension to * indicate to the server which signature/hash algorithm pairs may be * used in digital signatures.  The "extension_data" field of this * extension contains a "supported_signature_algorithms" value. * *     enum { *         none(0), md5(1), sha1(2), sha224(3), sha256(4), sha384(5), *         sha512(6), (255) *     } HashAlgorithm; * *     enum { anonymous(0), rsa(1), dsa(2), ecdsa(3), (255) } *       SignatureAlgorithm; * *     struct { *           HashAlgorithm hash; *           SignatureAlgorithm signature; *     } SignatureAndHashAlgorithm; * *     SignatureAndHashAlgorithm *       supported_signature_algorithms<2..2^16-2>; */final class SignatureAlgorithmsExtension extends HelloExtension {     private Collection<SignatureAndHashAlgorithm> algorithms;    private int algorithmsLen;  // length of supported_signature_algorithms     SignatureAlgorithmsExtension(            Collection<SignatureAndHashAlgorithm> signAlgs) {         super(ExtensionType.EXT_SIGNATURE_ALGORITHMS);         algorithms = new ArrayList<SignatureAndHashAlgorithm>(signAlgs);        algorithmsLen =            SignatureAndHashAlgorithm.sizeInRecord() * algorithms.size();    }     SignatureAlgorithmsExtension(HandshakeInStream s, int len)                throws IOException {        super(ExtensionType.EXT_SIGNATURE_ALGORITHMS);         algorithmsLen = s.getInt16();        if (algorithmsLen == 0 || algorithmsLen + 2 != len) {            throw new SSLProtocolException("Invalid " + type + " extension");        }         algorithms = new ArrayList<SignatureAndHashAlgorithm>();        int remains = algorithmsLen;        int sequence = 0;        while (remains > 1) {   // needs at least two bytes            int hash = s.getInt8();         // hash algorithm            int signature = s.getInt8();    // signature algorithm             SignatureAndHashAlgorithm algorithm =                SignatureAndHashAlgorithm.valueOf(hash, signature, ++sequence);            algorithms.add(algorithm);            remains -= 2;  // one byte for hash, one byte for signature        }         if (remains != 0) {            throw new SSLProtocolException("Invalid server_name extension");        }    }     Collection<SignatureAndHashAlgorithm> getSignAlgorithms() {        return algorithms;    }     @Override    int length() {        return 6 + algorithmsLen;    }     @Override    void send(HandshakeOutStream s) throws IOException {        s.putInt16(type.id);        s.putInt16(algorithmsLen + 2);        s.putInt16(algorithmsLen);         for (SignatureAndHashAlgorithm algorithm : algorithms) {            s.putInt8(algorithm.getHashValue());      // HashAlgorithm            s.putInt8(algorithm.getSignatureValue()); // SignatureAlgorithm        }    }     @Override    public String toString() {        StringBuffer buffer = new StringBuffer();        boolean opened = false;        for (SignatureAndHashAlgorithm signAlg : algorithms) {            if (opened) {                buffer.append(", " + signAlg.getAlgorithmName());            } else {                buffer.append(signAlg.getAlgorithmName());                opened = true;            }        }         return "Extension " + type + ", signature_algorithms: " + buffer;    }}

Lines 501–866 of 866. Previous lines