From 7628da200833d0d26215a91afdd1bf7fc110da1d Mon Sep 17 00:00:00 2001 From: Ben Perez Date: Fri, 23 Jun 2023 15:31:16 +0000 Subject: [PATCH] 8279254: PKCS9Attribute SigningTime always encoded in UTFTime Reviewed-by: jnimeh --- .../sun/security/pkcs/PKCS9Attribute.java | 7 +-- .../sun/security/util/DerInputStream.java | 6 +- .../sun/security/util/DerOutputStream.java | 19 +++++- .../classes/sun/security/util/DerValue.java | 10 +++- .../util/DerOutputStream/DerTimeEncoding.java | 58 +++++++++++++++++++ 5 files changed, 93 insertions(+), 7 deletions(-) create mode 100644 test/jdk/sun/security/util/DerOutputStream/DerTimeEncoding.java diff --git a/src/java.base/share/classes/sun/security/pkcs/PKCS9Attribute.java b/src/java.base/share/classes/sun/security/pkcs/PKCS9Attribute.java index 36fdc90704a..5031692ea73 100644 --- a/src/java.base/share/classes/sun/security/pkcs/PKCS9Attribute.java +++ b/src/java.base/share/classes/sun/security/pkcs/PKCS9Attribute.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2022, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2023, 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 @@ -463,8 +463,7 @@ public class PKCS9Attribute implements DerEncoder { case 5: // signing time byte elemTag = elems[0].getTag(); DerInputStream dis = new DerInputStream(elems[0].toByteArray()); - value = (elemTag == DerValue.tag_GeneralizedTime) ? - dis.getGeneralizedTime() : dis.getUTCTime(); + value = dis.getTime(); break; case 6: // countersignature @@ -570,7 +569,7 @@ public class PKCS9Attribute implements DerEncoder { case 5: // signing time { DerOutputStream temp2 = new DerOutputStream(); - temp2.putUTCTime((Date) value); + temp2.putTime((Date) value); temp.write(DerValue.tag_Set, temp2.toByteArray()); } break; diff --git a/src/java.base/share/classes/sun/security/util/DerInputStream.java b/src/java.base/share/classes/sun/security/util/DerInputStream.java index f12a3bb1510..8df4e80eb97 100644 --- a/src/java.base/share/classes/sun/security/util/DerInputStream.java +++ b/src/java.base/share/classes/sun/security/util/DerInputStream.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1996, 2022, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1996, 2023, 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 @@ -189,6 +189,10 @@ public class DerInputStream { return getDerValue().getGeneralString(); } + public Date getTime() throws IOException { + return getDerValue().getTime(); + } + public Date getUTCTime() throws IOException { return getDerValue().getUTCTime(); } diff --git a/src/java.base/share/classes/sun/security/util/DerOutputStream.java b/src/java.base/share/classes/sun/security/util/DerOutputStream.java index 4c85cb7e604..0cb7bc46f06 100644 --- a/src/java.base/share/classes/sun/security/util/DerOutputStream.java +++ b/src/java.base/share/classes/sun/security/util/DerOutputStream.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1996, 2022, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1996, 2023, 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 @@ -482,6 +482,23 @@ public final class DerOutputStream return this; } + /** + * 1/1/1950 is the lowest date that RFC 2630 serializes to UTC time + */ + private static final Date utcLow = new Date(-631152000000L); // Dates before 1/1/1950 + + /** + * 12/31/2049 is the highest date that RFC 2630 serializes to UTC time + */ + private static final Date utcHigh = new Date(2524607999000L); + + /** + * Takes a Date and chooses UTC or GeneralizedTime as per RFC 2630 + */ + public DerOutputStream putTime(Date d) { + return (d.before(utcLow) || d.after(utcHigh)) ? putGeneralizedTime(d) : putUTCTime(d); + } + /** * Marshals a DER UTC time/date value. * diff --git a/src/java.base/share/classes/sun/security/util/DerValue.java b/src/java.base/share/classes/sun/security/util/DerValue.java index f960326eb57..0a0cfef4762 100644 --- a/src/java.base/share/classes/sun/security/util/DerValue.java +++ b/src/java.base/share/classes/sun/security/util/DerValue.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1996, 2022, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1996, 2023, 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 @@ -1060,6 +1060,14 @@ public class DerValue { return b - '0'; } + /** + * Determines whether Date was encoded as UTC or Generalized time and + * calls getUTCTime or getGeneralizedTime accordingly + */ + public Date getTime() throws IOException { + return (tag == tag_UtcTime) ? getUTCTime() : getGeneralizedTime(); + } + /** * Returns a Date if the DerValue is UtcTime. * diff --git a/test/jdk/sun/security/util/DerOutputStream/DerTimeEncoding.java b/test/jdk/sun/security/util/DerOutputStream/DerTimeEncoding.java new file mode 100644 index 00000000000..1fbfc73f3d6 --- /dev/null +++ b/test/jdk/sun/security/util/DerOutputStream/DerTimeEncoding.java @@ -0,0 +1,58 @@ +/* + * Copyright (c) 2023, 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 + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/* + * @test + * @bug 8279254 + * @summary Changed time encoding to correctly use UTC between 1950-2050 and GeneralizedTime otherwise + * @library /test/lib + * @modules java.base/sun.security.util + */ + +import java.util.Date; +import sun.security.util.DerOutputStream; +import sun.security.util.DerValue; + +public class DerTimeEncoding { + public static void main(String args[]) throws Exception { + //Check that dates after 2050 use GeneralizedTime + DerOutputStream out = new DerOutputStream(); + Date generalizedTimeDate = new Date(2688854400000L); // Test date is 3/17/2055 + out.putTime(generalizedTimeDate); + DerValue val = new DerValue(out.toByteArray()); + if (val.tag != DerValue.tag_GeneralizedTime) { + System.out.println("putTime incorrectly serialized to UTC time instead of GeneralizedTime"); + throw new RuntimeException("Incorrect Der date format"); + } + + //Check dates between 1950-2050 use UTC time + out = new DerOutputStream(); + Date utcDate = new Date(242092800000L); //Test date is 9/3/1977 + out.putTime(utcDate); + val = new DerValue(out.toByteArray()); + if (val.tag != DerValue.tag_UtcTime) { + System.out.println("putTime incorrectly serialized to Generalized time instead of UTC time"); + throw new RuntimeException("Incorrect Der date format"); + } + } +} \ No newline at end of file