Path: blob/master/src/java.base/share/classes/sun/security/provider/certpath/OCSPNonceExtension.java
41161 views
/*1* Copyright (c) 2015, 2021, 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*/2425package sun.security.provider.certpath;2627import java.io.IOException;28import java.util.Objects;29import java.security.SecureRandom;3031import sun.security.x509.Extension;32import sun.security.x509.PKIXExtensions;33import sun.security.util.Debug;34import sun.security.util.DerValue;3536/**37* Represent the OCSP Nonce Extension.38* This extension, if present, provides a nonce value in OCSP requests39* and responses. This will cryptographically bind requests and responses40* and help to prevent replay attacks (see RFC 6960, section 4.4.1).41*42* @see Extension43*/44public final class OCSPNonceExtension extends Extension {4546/**47* Attribute name.48*/49private static final String EXTENSION_NAME = "OCSPNonce";50private byte[] nonceData = null;5152/**53* Create an {@code OCSPNonceExtension} by providing the nonce length.54* The criticality is set to false, and the OID for the extension will55* be the value defined by "id-pkix-ocsp-nonce" from RFC 6960.56*57* @param length the number of random bytes composing the nonce58*59* @throws IOException if any errors happen during encoding of the60* extension.61* @throws IllegalArgumentException if length is not a positive integer.62*/63public OCSPNonceExtension(int length) throws IOException {64this(false, length);65}6667/**68* Create an {@code OCSPNonceExtension} by providing the nonce length and69* criticality setting. The OID for the extension will70* be the value defined by "id-pkix-ocsp-nonce" from RFC 6960.71*72* @param isCritical a boolean flag indicating whether the criticality bit73* is set for this extension74* @param length the number of random bytes composing the nonce75*76* @throws IOException if any errors happen during encoding of the77* extension.78* @throws IllegalArgumentException if length is not in the range of 1 to 32.79*/80public OCSPNonceExtension(boolean isCritical, int length)81throws IOException {82this.extensionId = PKIXExtensions.OCSPNonce_Id;83this.critical = isCritical;8485// RFC 8954, section 2.1: the length of the nonce MUST be at least 1 octet86// and can be up to 32 octets.87if (length > 0 && length <= 32) {88SecureRandom rng = new SecureRandom();89this.nonceData = new byte[length];90rng.nextBytes(nonceData);91this.extensionValue = new DerValue(DerValue.tag_OctetString,92nonceData).toByteArray();93} else {94throw new IllegalArgumentException(95"Length of nonce must be at least 1 byte and can be up to 32 bytes");96}97}9899/**100* Create an {@code OCSPNonceExtension} by providing a nonce value.101* The criticality is set to false, and the OID for the extension will102* be the value defined by "id-pkix-ocsp-nonce" from RFC 6960.103*104* @param incomingNonce The nonce data to be set for the extension. This105* must be a non-null array of at least one byte long.106*107* @throws IOException if any errors happen during encoding of the108* extension.109* @throws IllegalArgumentException if the incomingNonce length is not a110* positive integer.111* @throws NullPointerException if the incomingNonce is null.112*/113public OCSPNonceExtension(byte[] incomingNonce) throws IOException {114this(false, incomingNonce);115}116117/**118* Create an {@code OCSPNonceExtension} by providing a nonce value and119* criticality setting. The OID for the extension will120* be the value defined by "id-pkix-ocsp-nonce" from RFC 6960.121*122* @param isCritical a boolean flag indicating whether the criticality bit123* is set for this extension124* @param incomingNonce The nonce data to be set for the extension. This125* must be a non-null array of at least one byte long and can be up to126* 32 bytes.127*128* @throws IOException if any errors happen during encoding of the129* extension.130* @throws IllegalArgumentException if the incomingNonce length is not131* in the range of 1 to 32.132* @throws NullPointerException if the incomingNonce is null.133*/134public OCSPNonceExtension(boolean isCritical, byte[] incomingNonce)135throws IOException {136this.extensionId = PKIXExtensions.OCSPNonce_Id;137this.critical = isCritical;138139Objects.requireNonNull(incomingNonce, "Nonce data must be non-null");140// RFC 8954, section 2.1: the length of the nonce MUST be at least 1 octet141// and can be up to 32 octets.142if (incomingNonce.length > 0 && incomingNonce.length <= 32) {143this.nonceData = incomingNonce.clone();144this.extensionValue = new DerValue(DerValue.tag_OctetString,145nonceData).toByteArray();146} else {147throw new IllegalArgumentException(148"Nonce data must be at least 1 byte and can be up to 32 bytes in length");149}150}151152/**153* Return the nonce bytes themselves, without any DER encoding.154*155* @return A copy of the underlying nonce bytes156*/157public byte[] getNonceValue() {158return nonceData.clone();159}160161/**162* Returns a printable representation of the {@code OCSPNonceExtension}.163*164* @return a string representation of the extension.165*/166@Override167public String toString() {168StringBuilder sb = new StringBuilder();169sb.append(super.toString()).append(EXTENSION_NAME).append(": ");170sb.append((nonceData == null) ? "" : Debug.toString(nonceData));171sb.append("\n");172return sb.toString();173}174175/**176* Return the name of the extension as a {@code String}177*178* @return the name of the extension179*/180public String getName() {181return EXTENSION_NAME;182}183}184185186