1 /*
   2  * Copyright (c) 2006, 2016, Oracle and/or its affiliates. All rights reserved.
   3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
   4  *
   5  * This code is free software; you can redistribute it and/or modify it
   6  * under the terms of the GNU General Public License version 2 only, as
   7  * published by the Free Software Foundation.  Oracle designates this
   8  * particular file as subject to the "Classpath" exception as provided
   9  * by Oracle in the LICENSE file that accompanied this code.
  10  *
  11  * This code is distributed in the hope that it will be useful, but WITHOUT
  12  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  13  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  14  * version 2 for more details (a copy is included in the LICENSE file that
  15  * accompanied this code).
  16  *
  17  * You should have received a copy of the GNU General Public License version
  18  * 2 along with this work; if not, write to the Free Software Foundation,
  19  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  20  *
  21  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  22  * or visit www.oracle.com if you need additional information or have any
  23  * questions.
  24  */
  25 
  26 package sun.security.ssl;
  27 
  28 import java.io.IOException;
  29 import java.util.ArrayList;
  30 import java.util.List;
  31 
  32 import javax.net.ssl.SSLProtocolException;
  33 
  34 final class EllipticPointFormatsExtension extends HelloExtension {
  35 
  36     static final int FMT_UNCOMPRESSED = 0;
  37     static final int FMT_ANSIX962_COMPRESSED_PRIME = 1;
  38     static final int FMT_ANSIX962_COMPRESSED_CHAR2 = 2;
  39 
  40     static final HelloExtension DEFAULT =
  41             new EllipticPointFormatsExtension(new byte[] {FMT_UNCOMPRESSED});
  42 
  43     private final byte[] formats;
  44 
  45     private EllipticPointFormatsExtension(byte[] formats) {
  46         super(ExtensionType.EXT_EC_POINT_FORMATS);
  47         this.formats = formats;
  48     }
  49 
  50     EllipticPointFormatsExtension(HandshakeInStream s, int len)
  51             throws IOException {
  52         super(ExtensionType.EXT_EC_POINT_FORMATS);
  53         formats = s.getBytes8();
  54         // RFC 4492 says uncompressed points must always be supported.
  55         // Check just to make sure.
  56         boolean uncompressed = false;
  57         for (int format : formats) {
  58             if (format == FMT_UNCOMPRESSED) {
  59                 uncompressed = true;
  60                 break;
  61             }
  62         }
  63         if (uncompressed == false) {
  64             throw new SSLProtocolException
  65                 ("Peer does not support uncompressed points");
  66         }
  67     }
  68 
  69     @Override
  70     int length() {
  71         return 5 + formats.length;
  72     }
  73 
  74     @Override
  75     void send(HandshakeOutStream s) throws IOException {
  76         s.putInt16(type.id);
  77         s.putInt16(formats.length + 1);
  78         s.putBytes8(formats);
  79     }
  80 
  81     private static String toString(byte format) {
  82         int f = format & 0xff;
  83         switch (f) {
  84         case FMT_UNCOMPRESSED:
  85             return "uncompressed";
  86         case FMT_ANSIX962_COMPRESSED_PRIME:
  87             return "ansiX962_compressed_prime";
  88         case FMT_ANSIX962_COMPRESSED_CHAR2:
  89             return "ansiX962_compressed_char2";
  90         default:
  91             return "unknown-" + f;
  92         }
  93     }
  94 
  95     @Override
  96     public String toString() {
  97         List<String> list = new ArrayList<String>();
  98         for (byte format : formats) {
  99             list.add(toString(format));
 100         }
 101         return "Extension " + type + ", formats: " + list;
 102     }
 103 }