001/* 002 * nimbus-jose-jwt 003 * 004 * Copyright 2012-2018, Connect2id Ltd. 005 * 006 * Licensed under the Apache License, Version 2.0 (the "License"); you may not use 007 * this file except in compliance with the License. You may obtain a copy of the 008 * License at 009 * 010 * http://www.apache.org/licenses/LICENSE-2.0 011 * 012 * Unless required by applicable law or agreed to in writing, software distributed 013 * under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR 014 * CONDITIONS OF ANY KIND, either express or implied. See the License for the 015 * specific language governing permissions and limitations under the License. 016 */ 017 018package com.nimbusds.jose.crypto; 019 020 021import java.util.Collections; 022import java.util.Set; 023import javax.crypto.SecretKey; 024 025import com.nimbusds.jose.*; 026import com.nimbusds.jose.crypto.impl.CriticalHeaderParamsDeferral; 027import com.nimbusds.jose.crypto.impl.ECDH; 028import com.nimbusds.jose.crypto.impl.ECDHCryptoProvider; 029import com.nimbusds.jose.jwk.Curve; 030import com.nimbusds.jose.jwk.OctetKeyPair; 031import com.nimbusds.jose.util.Base64URL; 032 033 034/** 035 * Curve25519 Elliptic Curve Diffie-Hellman decrypter of 036 * {@link com.nimbusds.jose.JWEObject JWE objects}. 037 * Expects a private {@link OctetKeyPair} key with {@code "crv"} X25519. 038 * 039 * <p>See <a href="https://tools.ietf.org/html/rfc8037">RFC 8037</a> 040 * for more information. 041 * 042 * <p>See also {@link ECDHDecrypter} for ECDH on other curves. 043 * 044 * <p>This class is thread-safe. 045 * 046 * <p>Supports the following key management algorithms: 047 * 048 * <ul> 049 * <li>{@link com.nimbusds.jose.JWEAlgorithm#ECDH_ES} 050 * <li>{@link com.nimbusds.jose.JWEAlgorithm#ECDH_ES_A128KW} 051 * <li>{@link com.nimbusds.jose.JWEAlgorithm#ECDH_ES_A192KW} 052 * <li>{@link com.nimbusds.jose.JWEAlgorithm#ECDH_ES_A256KW} 053 * </ul> 054 * 055 * <p>Supports the following elliptic curve: 056 * 057 * <ul> 058 * <li>{@link com.nimbusds.jose.jwk.Curve#X25519} (Curve25519) 059 * </ul> 060 * 061 * <p>Supports the following content encryption algorithms: 062 * 063 * <ul> 064 * <li>{@link com.nimbusds.jose.EncryptionMethod#A128CBC_HS256} 065 * <li>{@link com.nimbusds.jose.EncryptionMethod#A192CBC_HS384} 066 * <li>{@link com.nimbusds.jose.EncryptionMethod#A256CBC_HS512} 067 * <li>{@link com.nimbusds.jose.EncryptionMethod#A128GCM} 068 * <li>{@link com.nimbusds.jose.EncryptionMethod#A192GCM} 069 * <li>{@link com.nimbusds.jose.EncryptionMethod#A256GCM} 070 * <li>{@link com.nimbusds.jose.EncryptionMethod#A128CBC_HS256_DEPRECATED} 071 * <li>{@link com.nimbusds.jose.EncryptionMethod#A256CBC_HS512_DEPRECATED} 072 * <li>{@link com.nimbusds.jose.EncryptionMethod#XC20P} 073 * </ul> 074 * 075 * @author Tim McLean 076 * @version 2018-07-12 077 */ 078public class X25519Decrypter extends ECDHCryptoProvider implements JWEDecrypter, CriticalHeaderParamsAware { 079 080 081 /** 082 * The private key. 083 */ 084 private final OctetKeyPair privateKey; 085 086 087 /** 088 * The critical header policy. 089 */ 090 private final CriticalHeaderParamsDeferral critPolicy = new CriticalHeaderParamsDeferral(); 091 092 093 /** 094 * Creates a new Curve25519 Elliptic Curve Diffie-Hellman decrypter. 095 * 096 * @param privateKey The private key. Must not be {@code null}. 097 * 098 * @throws JOSEException If the key subtype is not supported. 099 */ 100 public X25519Decrypter(final OctetKeyPair privateKey) 101 throws JOSEException { 102 103 this(privateKey, null); 104 } 105 106 107 /** 108 * Creates a new Curve25519 Elliptic Curve Diffie-Hellman decrypter. 109 * 110 * @param privateKey The private key. Must not be {@code null}. 111 * @param defCritHeaders The names of the critical header parameters 112 * that are deferred to the application for 113 * processing, empty set or {@code null} if none. 114 * 115 * @throws JOSEException If the key subtype is not supported. 116 */ 117 public X25519Decrypter(final OctetKeyPair privateKey, final Set<String> defCritHeaders) 118 throws JOSEException { 119 120 super(privateKey.getCurve()); 121 122 if (! Curve.X25519.equals(privateKey.getCurve())) { 123 throw new JOSEException("X25519Decrypter only supports OctetKeyPairs with crv=X25519"); 124 } 125 126 if (! privateKey.isPrivate()) { 127 throw new JOSEException("The OctetKeyPair doesn't contain a private part"); 128 } 129 130 this.privateKey = privateKey; 131 132 critPolicy.setDeferredCriticalHeaderParams(defCritHeaders); 133 } 134 135 136 @Override 137 public Set<Curve> supportedEllipticCurves() { 138 139 return Collections.singleton(Curve.X25519); 140 } 141 142 143 /** 144 * Returns the private key. 145 * 146 * @return The private key. 147 */ 148 public OctetKeyPair getPrivateKey() { 149 150 return privateKey; 151 } 152 153 154 @Override 155 public Set<String> getProcessedCriticalHeaderParams() { 156 157 return critPolicy.getProcessedCriticalHeaderParams(); 158 } 159 160 161 @Override 162 public Set<String> getDeferredCriticalHeaderParams() { 163 164 return critPolicy.getProcessedCriticalHeaderParams(); 165 } 166 167 168 @Override 169 public byte[] decrypt(final JWEHeader header, 170 final Base64URL encryptedKey, 171 final Base64URL iv, 172 final Base64URL cipherText, 173 final Base64URL authTag) 174 throws JOSEException { 175 176 // Check for unrecognizable "crit" properties 177 critPolicy.ensureHeaderPasses(header); 178 179 // Get ephemeral key from header 180 OctetKeyPair ephemeralPublicKey = (OctetKeyPair) header.getEphemeralPublicKey(); 181 182 if (ephemeralPublicKey == null) { 183 throw new JOSEException("Missing ephemeral public key epk JWE header parameter"); 184 } 185 186 if (! privateKey.getCurve().equals(ephemeralPublicKey.getCurve())) { 187 throw new JOSEException("Curve of ephemeral public key does not match curve of private key"); 188 } 189 190 // Derive 'Z' 191 // Note: X25519 does not require public key validation 192 // See https://cr.yp.to/ecdh.html#validate 193 SecretKey Z = ECDH.deriveSharedSecret(ephemeralPublicKey, privateKey); 194 195 return decryptWithZ(header, Z, encryptedKey, iv, cipherText, authTag); 196 } 197}