From 2cdaff4d82aa3e158b4da3b62bccff25f91037f7 Mon Sep 17 00:00:00 2001 From: weijun Date: Wed, 14 Jun 2017 12:32:17 +0800 Subject: [PATCH] 8181841: A TSA server returns timestamp with precision higher than milliseconds Reviewed-by: vinnie --- .../sun/security/util/DerInputBuffer.java | 48 +++++++++---------- .../util/DerInputBuffer/TimeParsing.java | 19 ++++++-- 2 files changed, 39 insertions(+), 28 deletions(-) diff --git a/src/share/classes/sun/security/util/DerInputBuffer.java b/src/share/classes/sun/security/util/DerInputBuffer.java index 54eade390..acc0def21 100644 --- a/src/share/classes/sun/security/util/DerInputBuffer.java +++ b/src/share/classes/sun/security/util/DerInputBuffer.java @@ -27,7 +27,6 @@ package sun.security.util; 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 @@ class DerInputBuffer extends ByteArrayInputStream implements Cloneable { 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 @@ class DerInputBuffer extends ByteArrayInputStream implements Cloneable { */ 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 @@ class DerInputBuffer extends ByteArrayInputStream implements Cloneable { 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; } diff --git a/test/sun/security/util/DerInputBuffer/TimeParsing.java b/test/sun/security/util/DerInputBuffer/TimeParsing.java index a81b4b275..75a7ee49f 100644 --- a/test/sun/security/util/DerInputBuffer/TimeParsing.java +++ b/test/sun/security/util/DerInputBuffer/TimeParsing.java @@ -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 */ @@ -76,6 +76,10 @@ public class TimeParsing { 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}; @@ -88,10 +92,17 @@ public class TimeParsing { 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); @@ -145,6 +156,8 @@ public class TimeParsing { 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)"); } - } -- GitLab