8234418: Better parsing with CertificateFactory

Reviewed-by: weijun, mschoene, rhalade
diff --git a/src/java.base/share/classes/sun/security/util/DerInputBuffer.java b/src/java.base/share/classes/sun/security/util/DerInputBuffer.java
index 1df6059..a5cf8fd 100644
--- a/src/java.base/share/classes/sun/security/util/DerInputBuffer.java
+++ b/src/java.base/share/classes/sun/security/util/DerInputBuffer.java
@@ -354,8 +354,12 @@
             second += toDigit(buf[pos++], type);
             len -= 2;
             // handle fractional seconds (if present)
-            if (buf[pos] == '.' || buf[pos] == ',') {
+            if (generalized && (buf[pos] == '.' || buf[pos] == ',')) {
                 len --;
+                if (len == 0) {
+                    throw new IOException("Parse " + type +
+                            " time, empty fractional part");
+                }
                 pos++;
                 int precision = 0;
                 while (buf[pos] != 'Z' &&
@@ -365,6 +369,11 @@
                     // store millisecond precision only
                     int thisDigit = toDigit(buf[pos], type);
                     precision++;
+                    len--;
+                    if (len == 0) {
+                        throw new IOException("Parse " + type +
+                                " time, invalid fractional part");
+                    }
                     pos++;
                     switch (precision) {
                         case 1:
@@ -382,7 +391,6 @@
                     throw new IOException("Parse " + type +
                             " time, empty fractional part");
                 }
-                len -= precision;
             }
         } else
             second = 0;
@@ -412,6 +420,9 @@
 
         switch (buf[pos++]) {
         case '+':
+            if (len != 5) {
+                throw new IOException("Parse " + type + " time, invalid offset");
+            }
             hr = 10 * toDigit(buf[pos++], type);
             hr += toDigit(buf[pos++], type);
             min = 10 * toDigit(buf[pos++], type);
@@ -424,6 +435,9 @@
             break;
 
         case '-':
+            if (len != 5) {
+                throw new IOException("Parse " + type + " time, invalid offset");
+            }
             hr = 10 * toDigit(buf[pos++], type);
             hr += toDigit(buf[pos++], type);
             min = 10 * toDigit(buf[pos++], type);
@@ -436,6 +450,9 @@
             break;
 
         case 'Z':
+            if (len != 1) {
+                throw new IOException("Parse " + type + " time, invalid format");
+            }
             break;
 
         default: