8181841: A TSA server returns timestamp with precision higher than milliseconds
authorweijun
Wed, 14 Jun 2017 12:32:17 +0800
changeset 45472 c7f7547dd4e4
parent 45471 91b94351a742
child 45474 78b7a8c8fc06
8181841: A TSA server returns timestamp with precision higher than milliseconds Reviewed-by: vinnie
jdk/src/java.base/share/classes/sun/security/util/DerInputBuffer.java
jdk/test/sun/security/util/DerInputBuffer/TimeParsing.java
--- a/jdk/src/java.base/share/classes/sun/security/util/DerInputBuffer.java	Wed Jun 14 11:55:43 2017 +0800
+++ b/jdk/src/java.base/share/classes/sun/security/util/DerInputBuffer.java	Wed Jun 14 12:32:17 2017 +0800
@@ -27,7 +27,6 @@
 
 import java.io.ByteArrayInputStream;
 import java.io.IOException;
-import java.io.OutputStream;
 import java.math.BigInteger;
 import java.util.Date;
 import sun.util.calendar.CalendarDate;
@@ -275,7 +274,7 @@
         if (len > available())
             throw new IOException("short read of DER Generalized Time");
 
-        if (len < 13 || len > 23)
+        if (len < 13)
             throw new IOException("DER Generalized Time length error");
 
         return getTime(len, true);
@@ -350,7 +349,7 @@
          */
 
         millis = 0;
-        if (len > 2 && len < 12) {
+        if (len > 2) {
             second = 10 * Character.digit((char)buf[pos++], 10);
             second += Character.digit((char)buf[pos++], 10);
             len -= 2;
@@ -358,31 +357,30 @@
             if (buf[pos] == '.' || buf[pos] == ',') {
                 len --;
                 pos++;
-                // handle upto milisecond precision only
                 int precision = 0;
-                int peek = pos;
-                while (buf[peek] != 'Z' &&
-                       buf[peek] != '+' &&
-                       buf[peek] != '-') {
-                    peek++;
+                while (buf[pos] != 'Z' &&
+                       buf[pos] != '+' &&
+                       buf[pos] != '-') {
+                    // Validate all digits in the fractional part but
+                    // store millisecond precision only
+                    int thisDigit = Character.digit((char)buf[pos], 10);
                     precision++;
+                    pos++;
+                    switch (precision) {
+                        case 1:
+                            millis += 100 * thisDigit;
+                            break;
+                        case 2:
+                            millis += 10 * thisDigit;
+                            break;
+                        case 3:
+                            millis += thisDigit;
+                            break;
+                    }
                 }
-                switch (precision) {
-                case 3:
-                    millis += 100 * Character.digit((char)buf[pos++], 10);
-                    millis += 10 * Character.digit((char)buf[pos++], 10);
-                    millis += Character.digit((char)buf[pos++], 10);
-                    break;
-                case 2:
-                    millis += 100 * Character.digit((char)buf[pos++], 10);
-                    millis += 10 * Character.digit((char)buf[pos++], 10);
-                    break;
-                case 1:
-                    millis += 100 * Character.digit((char)buf[pos++], 10);
-                    break;
-                default:
-                        throw new IOException("Parse " + type +
-                            " time, unsupported precision for seconds value");
+                if (precision == 0) {
+                    throw new IOException("Parse " + type +
+                            " time, empty fractional part");
                 }
                 len -= precision;
             }
--- a/jdk/test/sun/security/util/DerInputBuffer/TimeParsing.java	Wed Jun 14 11:55:43 2017 +0800
+++ b/jdk/test/sun/security/util/DerInputBuffer/TimeParsing.java	Wed Jun 14 12:32:17 2017 +0800
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2002, 2003, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2002, 2017, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -23,7 +23,7 @@
 
 /*
  * @test
- * @bug 4558835 4915146
+ * @bug 4558835 4915146 8181841
  * @summary Verify timezone offset and fractional seconds are correctly parsed
  * @modules java.base/sun.security.util
  */
@@ -77,6 +77,10 @@
   private final static byte[] GEN_FRACT3_ZULU =
     {0x18, 0x13, 0x32, 0x30, 0x30, 0x31, 0x30, 0x38, 0x31, 0x30, 0x31, 0x37, 0x34, 0x33, 0x35, 0x31, 0x2e, 0x37, 0x36, 0x35, 0x5a};
 
+  // 20010810174351.7654Z
+  private final static byte[] GEN_FRACT4_ZULU =
+    {0x18, 0x14, 0x32, 0x30, 0x30, 0x31, 0x30, 0x38, 0x31, 0x30, 0x31, 0x37, 0x34, 0x33, 0x35, 0x31, 0x2e, 0x37, 0x36, 0x35, 0x34, 0x5a};
+
   // 20010810184351.7+0100
   private final static byte[] GEN_FRACT1_PLUS1 =
     {0x18, 0x15, 0x32, 0x30, 0x30, 0x31, 0x30, 0x38, 0x31, 0x30, 0x31, 0x38, 0x34, 0x33, 0x35, 0x31, 0x2e, 0x37, 0x2b, 0x30, 0x31, 0x30, 0x30};
@@ -89,10 +93,17 @@
   private final static byte[] GEN_FRACT3_PLUS1 =
     {0x18, 0x17, 0x32, 0x30, 0x30, 0x31, 0x30, 0x38, 0x31, 0x30, 0x31, 0x38, 0x34, 0x33, 0x35, 0x31, 0x2e, 0x37, 0x36, 0x35, 0x2b, 0x30, 0x31, 0x30, 0x30};
 
+  // 20010810184351.7654+0100
+  private final static byte[] GEN_FRACT4_PLUS1 =
+    {0x18, 0x18, 0x32, 0x30, 0x30, 0x31, 0x30, 0x38, 0x31, 0x30, 0x31, 0x38, 0x34, 0x33, 0x35, 0x31, 0x2e, 0x37, 0x36, 0x35, 0x34, 0x2b, 0x30, 0x31, 0x30, 0x30};
+
   // 20010810184351,765+0100
   private final static byte[] GEN_FRACT3_COMMA_PLUS1 =
     {0x18, 0x17, 0x32, 0x30, 0x30, 0x31, 0x30, 0x38, 0x31, 0x30, 0x31, 0x38, 0x34, 0x33, 0x35, 0x31, 0x2c, 0x37, 0x36, 0x35, 0x2b, 0x30, 0x31, 0x30, 0x30};
 
+  // 20010810184351,7654+0100
+  private final static byte[] GEN_FRACT4_COMMA_PLUS1 =
+    {0x18, 0x18, 0x32, 0x30, 0x30, 0x31, 0x30, 0x38, 0x31, 0x30, 0x31, 0x38, 0x34, 0x33, 0x35, 0x31, 0x2c, 0x37, 0x36, 0x35, 0x34, 0x2b, 0x30, 0x31, 0x30, 0x30};
 
   private static Date decodeUTC(byte[] b) throws IOException {
     DerInputStream derin = new DerInputStream(b);
@@ -146,6 +157,8 @@
     checkGeneralized(d3, GEN_FRACT3_ZULU, "fractional seconds (Zulu)");
     checkGeneralized(d3, GEN_FRACT3_PLUS1, "fractional seconds (+0100)");
     checkGeneralized(d3, GEN_FRACT3_COMMA_PLUS1, "fractional seconds (+0100)");
+    checkGeneralized(d3, GEN_FRACT4_ZULU, "fractional seconds (Zulu)");
+    checkGeneralized(d3, GEN_FRACT4_PLUS1, "fractional seconds (+0100)");
+    checkGeneralized(d3, GEN_FRACT4_COMMA_PLUS1, "fractional seconds (+0100)");
   }
-
 }