Path: blob/master/src/java.base/share/classes/sun/security/x509/CertificateValidity.java
41159 views
/*1* Copyright (c) 1997, 2020, Oracle and/or its affiliates. All rights reserved.2* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.3*4* This code is free software; you can redistribute it and/or modify it5* under the terms of the GNU General Public License version 2 only, as6* published by the Free Software Foundation. Oracle designates this7* particular file as subject to the "Classpath" exception as provided8* by Oracle in the LICENSE file that accompanied this code.9*10* This code is distributed in the hope that it will be useful, but WITHOUT11* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or12* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License13* version 2 for more details (a copy is included in the LICENSE file that14* accompanied this code).15*16* You should have received a copy of the GNU General Public License version17* 2 along with this work; if not, write to the Free Software Foundation,18* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.19*20* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA21* or visit www.oracle.com if you need additional information or have any22* questions.23*/24package sun.security.x509;2526import java.io.IOException;27import java.io.OutputStream;28import java.security.cert.*;29import java.util.Date;30import java.util.Enumeration;3132import sun.security.util.*;3334/**35* This class defines the interval for which the certificate is valid.36*37* @author Amit Kapoor38* @author Hemma Prafullchandra39* @see CertAttrSet40*/41public class CertificateValidity implements CertAttrSet<String> {42/**43* Identifier for this attribute, to be used with the44* get, set, delete methods of Certificate, x509 type.45*/46public static final String IDENT = "x509.info.validity";47/**48* Sub attributes name for this CertAttrSet.49*/50public static final String NAME = "validity";51public static final String NOT_BEFORE = "notBefore";52public static final String NOT_AFTER = "notAfter";53/**54* YR_2050 date and time set to Jan01 00:00 2050 GMT55*/56static final long YR_2050 = 2524608000000L;5758// Private data members59private Date notBefore;60private Date notAfter;6162// Returns the first time the certificate is valid.63private Date getNotBefore() {64return (new Date(notBefore.getTime()));65}6667// Returns the last time the certificate is valid.68private Date getNotAfter() {69return (new Date(notAfter.getTime()));70}7172// Construct the class from the DerValue73private void construct(DerValue derVal) throws IOException {74if (derVal.tag != DerValue.tag_Sequence) {75throw new IOException("Invalid encoded CertificateValidity, " +76"starting sequence tag missing.");77}78// check if UTCTime encoded or GeneralizedTime79if (derVal.data.available() == 0)80throw new IOException("No data encoded for CertificateValidity");8182DerInputStream derIn = new DerInputStream(derVal.toByteArray());83DerValue[] seq = derIn.getSequence(2);84if (seq.length != 2)85throw new IOException("Invalid encoding for CertificateValidity");8687if (seq[0].tag == DerValue.tag_UtcTime) {88notBefore = derVal.data.getUTCTime();89} else if (seq[0].tag == DerValue.tag_GeneralizedTime) {90notBefore = derVal.data.getGeneralizedTime();91} else {92throw new IOException("Invalid encoding for CertificateValidity");93}9495if (seq[1].tag == DerValue.tag_UtcTime) {96notAfter = derVal.data.getUTCTime();97} else if (seq[1].tag == DerValue.tag_GeneralizedTime) {98notAfter = derVal.data.getGeneralizedTime();99} else {100throw new IOException("Invalid encoding for CertificateValidity");101}102}103104/**105* Default constructor for the class.106*/107public CertificateValidity() { }108109/**110* The default constructor for this class for the specified interval.111*112* @param notBefore the date and time before which the certificate113* is not valid.114* @param notAfter the date and time after which the certificate is115* not valid.116*/117public CertificateValidity(Date notBefore, Date notAfter) {118this.notBefore = notBefore;119this.notAfter = notAfter;120}121122/**123* Create the object, decoding the values from the passed DER stream.124*125* @param in the DerInputStream to read the CertificateValidity from.126* @exception IOException on decoding errors.127*/128public CertificateValidity(DerInputStream in) throws IOException {129DerValue derVal = in.getDerValue();130construct(derVal);131}132133/**134* Return the validity period as user readable string.135*/136public String toString() {137if (notBefore == null || notAfter == null)138return "";139return "Validity: [From: " + notBefore +140",\n To: " + notAfter + ']';141}142143/**144* Encode the CertificateValidity period in DER form to the stream.145*146* @param out the OutputStream to marshal the contents to.147* @exception IOException on errors.148*/149public void encode(OutputStream out) throws IOException {150151// in cases where default constructor is used check for152// null values153if (notBefore == null || notAfter == null) {154throw new IOException("CertAttrSet:CertificateValidity:" +155" null values to encode.\n");156}157DerOutputStream pair = new DerOutputStream();158159if (notBefore.getTime() < YR_2050) {160pair.putUTCTime(notBefore);161} else162pair.putGeneralizedTime(notBefore);163164if (notAfter.getTime() < YR_2050) {165pair.putUTCTime(notAfter);166} else {167pair.putGeneralizedTime(notAfter);168}169DerOutputStream seq = new DerOutputStream();170seq.write(DerValue.tag_Sequence, pair);171172out.write(seq.toByteArray());173}174175/**176* Set the attribute value.177*/178public void set(String name, Object obj) throws IOException {179if (!(obj instanceof Date)) {180throw new IOException("Attribute must be of type Date.");181}182if (name.equalsIgnoreCase(NOT_BEFORE)) {183notBefore = (Date)obj;184} else if (name.equalsIgnoreCase(NOT_AFTER)) {185notAfter = (Date)obj;186} else {187throw new IOException("Attribute name not recognized by " +188"CertAttrSet: CertificateValidity.");189}190}191192/**193* Get the attribute value.194*/195public Date get(String name) throws IOException {196if (name.equalsIgnoreCase(NOT_BEFORE)) {197return (getNotBefore());198} else if (name.equalsIgnoreCase(NOT_AFTER)) {199return (getNotAfter());200} else {201throw new IOException("Attribute name not recognized by " +202"CertAttrSet: CertificateValidity.");203}204}205206/**207* Delete the attribute value.208*/209public void delete(String name) throws IOException {210if (name.equalsIgnoreCase(NOT_BEFORE)) {211notBefore = null;212} else if (name.equalsIgnoreCase(NOT_AFTER)) {213notAfter = null;214} else {215throw new IOException("Attribute name not recognized by " +216"CertAttrSet: CertificateValidity.");217}218}219220/**221* Return an enumeration of names of attributes existing within this222* attribute.223*/224public Enumeration<String> getElements() {225AttributeNameEnumeration elements = new AttributeNameEnumeration();226elements.addElement(NOT_BEFORE);227elements.addElement(NOT_AFTER);228229return (elements.elements());230}231232/**233* Return the name of this attribute.234*/235public String getName() {236return (NAME);237}238239/**240* Verify that the current time is within the validity period.241*242* @exception CertificateExpiredException if the certificate has expired.243* @exception CertificateNotYetValidException if the certificate is not244* yet valid.245*/246public void valid()247throws CertificateNotYetValidException, CertificateExpiredException {248Date now = new Date();249valid(now);250}251252/**253* Verify that the passed time is within the validity period.254* @param now the Date against which to compare the validity255* period.256*257* @exception CertificateExpiredException if the certificate has expired258* with respect to the <code>Date</code> supplied.259* @exception CertificateNotYetValidException if the certificate is not260* yet valid with respect to the <code>Date</code> supplied.261*262*/263public void valid(Date now)264throws CertificateNotYetValidException, CertificateExpiredException {265/*266* we use the internal Dates rather than the passed in Date267* because someone could override the Date methods after()268* and before() to do something entirely different.269*/270if (notBefore.after(now)) {271throw new CertificateNotYetValidException("NotBefore: " +272notBefore.toString());273}274if (notAfter.before(now)) {275throw new CertificateExpiredException("NotAfter: " +276notAfter.toString());277}278}279}280281282