001/*
002 * The contents of this file are subject to the terms of the Common Development and
003 * Distribution License (the License). You may not use this file except in compliance with the
004 * License.
005 *
006 * You can obtain a copy of the License at legal/CDDLv1.0.txt. See the License for the
007 * specific language governing permission and limitations under the License.
008 *
009 * When distributing Covered Software, include this CDDL Header Notice in each file and include
010 * the License file at legal/CDDLv1.0.txt. If applicable, add the following below the CDDL
011 * Header, with the fields enclosed by brackets [] replaced by your own identifying
012 * information: "Portions copyright [year] [name of copyright owner]".
013 *
014 * Copyright 2013-2015 ForgeRock AS.
015 */
016
017package org.forgerock.json.jose.jwe;
018
019import java.util.Map;
020
021import org.forgerock.json.jose.jwk.JWK;
022import org.forgerock.json.jose.jws.JwtSecureHeader;
023
024/**
025 * An implementation for the JWE Header parameters.
026 *
027 * @since 2.0.0
028 */
029public class JweHeader extends JwtSecureHeader {
030
031    private static final String ENCRYPTION_METHOD_HEADER_KEY = "enc";
032    private static final String EPHEMERAL_PUBLIC_KEY_HEADER_KEY = "epk";
033    private static final String COMPRESSION_ALGORITHM_HEADER_KEY = "zip";
034    private static final String AGREEMENT_PARTY_UINFO_HEADER_KEY = "apu";   //Base64url
035
036    /**
037     * Constructs an new, empty JweHeader.
038     */
039    public JweHeader() {
040        super();
041    }
042
043    /**
044     * Constructs a new JweHeader with its parameters set to the contents of the given Map.
045     *
046     * @param headerParameters A Map containing the parameters to be set in the header.
047     */
048    public JweHeader(Map<String, Object> headerParameters)  {
049        super(headerParameters);
050    }
051
052    /**
053     * Gets the Algorithm set in the JWT header.
054     * <p>
055     * If there is no algorithm set in the JWT header, then the JweAlgorithm NONE will be returned.
056     *
057     * @return {@inheritDoc}
058     */
059    @Override
060    public JweAlgorithm getAlgorithm() {
061        return JweAlgorithm.valueOf(getAlgorithmString());
062    }
063
064    /**
065     * Sets the Encryption Method header parameter for this JWE.
066     * <p>
067     * Identifies the block encryption algorithm used to encrypt the Plaintext to produce the Ciphertext.
068     *
069     * @param encryptionMethod The Encryption Method.
070     */
071    public void setEncryptionMethod(EncryptionMethod encryptionMethod) {
072        put(ENCRYPTION_METHOD_HEADER_KEY, encryptionMethod.toString());
073    }
074
075    /**
076     * Gets the Encryption Method header parameter for this JWE.
077     *
078     * @return The Encryption Method.
079     */
080    public EncryptionMethod getEncryptionMethod() {
081        return EncryptionMethod.valueOf(get(ENCRYPTION_METHOD_HEADER_KEY).asString());
082    }
083
084    /**
085     * Sets the Ephemeral Public Key header parameter for this JWE.
086     * <p>
087     * For use in key agreement algorithms. When the Algorithm header parameter value specified identifies an algorithm
088     * for which "epk" is a parameter, this parameter MUST be present if REQUIRED by the algorithm.
089     *
090     * @param ephemeralPublicKey The Ephemeral Public Key.
091     */
092    public void setEphemeralPublicKey(JWK ephemeralPublicKey) {
093        put(EPHEMERAL_PUBLIC_KEY_HEADER_KEY, ephemeralPublicKey.toString());
094    }
095
096    /**
097     * Gets the Ephemeral Public Key header parameter for this JWE.
098     *
099     * @return The Ephemeral Public Key.
100     */
101    public String getEphemeralPublicKey() {
102        return get(EPHEMERAL_PUBLIC_KEY_HEADER_KEY).asString();
103    }
104
105    /**
106     * Sets the Compression Algorithm header parameter for this JWE.
107     * <p>
108     * If present, the value of the Compression Algorithm header parameter MUST be CompressionAlgorithm constant DEF.
109     *
110     * @param compressionAlgorithm The Compression Algorithm.
111     */
112    public void setCompressionAlgorithm(CompressionAlgorithm compressionAlgorithm) {
113        put(COMPRESSION_ALGORITHM_HEADER_KEY, compressionAlgorithm.toString());
114    }
115
116    /**
117     * Gets the Compression Algorithm header parameter for this JWE.
118     *
119     * @return The Compression Algorithm.
120     */
121    public CompressionAlgorithm getCompressionAlgorithm() {
122        String compressionAlgorithm = get(COMPRESSION_ALGORITHM_HEADER_KEY).asString();
123        if (compressionAlgorithm == null) {
124            return CompressionAlgorithm.NONE;
125        } else {
126            return CompressionAlgorithm.valueOf(compressionAlgorithm);
127        }
128    }
129
130    /**
131     * Sets the Agreement PartyUInfo header parameter for this JWE.
132     * <p>
133     * For use with key agreement algorithms (such as "ECDH-ES"), represented as a base64url encoded string.
134     * <p>
135     * This method will perform the base64url encoding so the agreementPartyUInfo must be the un-encoded String value
136     * of the Agreement PartyUInfo.
137     *
138     * @param agreementPartyUInfo The Agreement PartyUInfo.
139     */
140    public void setAgreementPartyUInfo(String agreementPartyUInfo) {
141        put(AGREEMENT_PARTY_UINFO_HEADER_KEY, agreementPartyUInfo);
142    }
143
144    /**
145     * Gets the Agreement PartyUInfo header parameter for this JWE.
146     *
147     * @return The Agreement PartyUInfo.
148     */
149    public String getAgreementPartyUInfo() {
150        return get(AGREEMENT_PARTY_UINFO_HEADER_KEY).asString();
151    }
152
153    /**
154     * {@inheritDoc}
155     */
156    @Override
157    public void setParameter(String key, Object value) {
158        JweHeaderKey headerKey = JweHeaderKey.getHeaderKey(key.toUpperCase());
159
160        switch (headerKey) {
161        case ENC: {
162            if (isValueOfType(value, EncryptionMethod.class)) {
163                setEncryptionMethod((EncryptionMethod) value);
164            }
165            checkValueIsOfType(value, String.class);
166            setEncryptionMethod(EncryptionMethod.parseMethod((String) value));
167            break;
168        }
169        case EPK: {
170            checkValueIsOfType(value, JWK.class);
171            setEphemeralPublicKey((JWK) value);
172            break;
173        }
174        case ZIP: {
175            if (isValueOfType(value, CompressionAlgorithm.class)) {
176                setCompressionAlgorithm((CompressionAlgorithm) value);
177            }
178            checkValueIsOfType(value, String.class);
179            setCompressionAlgorithm(CompressionAlgorithm.parseAlgorithm((String) value));
180            break;
181        }
182        case APU: {
183            checkValueIsOfType(value, String.class);
184            setAgreementPartyUInfo((String) value);
185            break;
186        }
187        default: {
188            super.setParameter(key, value);
189        }
190        }
191    }
192
193    /**
194     * {@inheritDoc}
195     */
196    @Override
197    public Object getParameter(String key) {
198        JweHeaderKey headerKey = JweHeaderKey.getHeaderKey(key.toUpperCase());
199
200        Object value;
201
202        switch (headerKey) {
203        case ENC: {
204            value = getEncryptionMethod();
205            break;
206        }
207        case EPK: {
208            value = getEphemeralPublicKey();
209            break;
210        }
211        case ZIP: {
212            value = getCompressionAlgorithm();
213            break;
214        }
215        case APU: {
216            value = getAgreementPartyUInfo();
217            break;
218        }
219        default: {
220            value = super.getParameter(key);
221        }
222        }
223
224        return value;
225    }
226}