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-2016 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 AGREEMENT_PARTY_UINFO_HEADER_KEY = "apu";   //Base64url
034
035    /**
036     * Constructs an new, empty JweHeader.
037     */
038    public JweHeader() {
039        super();
040    }
041
042    /**
043     * Constructs a new JweHeader with its parameters set to the contents of the given Map.
044     *
045     * @param headerParameters A Map containing the parameters to be set in the header.
046     */
047    public JweHeader(Map<String, Object> headerParameters)  {
048        super(headerParameters);
049    }
050
051    /**
052     * Gets the Algorithm set in the JWT header.
053     * <p>
054     * If there is no algorithm set in the JWT header, then the JweAlgorithm NONE will be returned.
055     *
056     * @return {@inheritDoc}
057     */
058    @Override
059    public JweAlgorithm getAlgorithm() {
060        return JweAlgorithm.parseAlgorithm(getAlgorithmString());
061    }
062
063    /**
064     * Sets the Encryption Method header parameter for this JWE.
065     * <p>
066     * Identifies the block encryption algorithm used to encrypt the Plaintext to produce the Ciphertext.
067     *
068     * @param encryptionMethod The Encryption Method.
069     */
070    public void setEncryptionMethod(EncryptionMethod encryptionMethod) {
071        put(ENCRYPTION_METHOD_HEADER_KEY, encryptionMethod.toString());
072    }
073
074    /**
075     * Gets the Encryption Method header parameter for this JWE.
076     *
077     * @return The Encryption Method.
078     */
079    public EncryptionMethod getEncryptionMethod() {
080        return EncryptionMethod.parseMethod(get(ENCRYPTION_METHOD_HEADER_KEY).asString());
081    }
082
083    /**
084     * Sets the Ephemeral Public Key header parameter for this JWE.
085     * <p>
086     * For use in key agreement algorithms. When the Algorithm header parameter value specified identifies an algorithm
087     * for which "epk" is a parameter, this parameter MUST be present if REQUIRED by the algorithm.
088     *
089     * @param ephemeralPublicKey The Ephemeral Public Key.
090     */
091    public void setEphemeralPublicKey(JWK ephemeralPublicKey) {
092        put(EPHEMERAL_PUBLIC_KEY_HEADER_KEY, ephemeralPublicKey.toString());
093    }
094
095    /**
096     * Gets the Ephemeral Public Key header parameter for this JWE.
097     *
098     * @return The Ephemeral Public Key.
099     */
100    public String getEphemeralPublicKey() {
101        return get(EPHEMERAL_PUBLIC_KEY_HEADER_KEY).asString();
102    }
103
104
105    /**
106     * Sets the Agreement PartyUInfo header parameter for this JWE.
107     * <p>
108     * For use with key agreement algorithms (such as "ECDH-ES"), represented as a base64url encoded string.
109     * <p>
110     * This method will perform the base64url encoding so the agreementPartyUInfo must be the un-encoded String value
111     * of the Agreement PartyUInfo.
112     *
113     * @param agreementPartyUInfo The Agreement PartyUInfo.
114     */
115    public void setAgreementPartyUInfo(String agreementPartyUInfo) {
116        put(AGREEMENT_PARTY_UINFO_HEADER_KEY, agreementPartyUInfo);
117    }
118
119    /**
120     * Gets the Agreement PartyUInfo header parameter for this JWE.
121     *
122     * @return The Agreement PartyUInfo.
123     */
124    public String getAgreementPartyUInfo() {
125        return get(AGREEMENT_PARTY_UINFO_HEADER_KEY).asString();
126    }
127
128    @Override
129    public void setParameter(String key, Object value) {
130        JweHeaderKey headerKey = JweHeaderKey.getHeaderKey(key.toUpperCase());
131
132        switch (headerKey) {
133        case ENC: {
134            if (isValueOfType(value, EncryptionMethod.class)) {
135                setEncryptionMethod((EncryptionMethod) value);
136            }
137            checkValueIsOfType(value, String.class);
138            setEncryptionMethod(EncryptionMethod.parseMethod((String) value));
139            break;
140        }
141        case EPK: {
142            checkValueIsOfType(value, JWK.class);
143            setEphemeralPublicKey((JWK) value);
144            break;
145        }
146        case ZIP: {
147            if (isValueOfType(value, CompressionAlgorithm.class)) {
148                setCompressionAlgorithm((CompressionAlgorithm) value);
149            }
150            checkValueIsOfType(value, String.class);
151            setCompressionAlgorithm(CompressionAlgorithm.parseAlgorithm((String) value));
152            break;
153        }
154        case APU: {
155            checkValueIsOfType(value, String.class);
156            setAgreementPartyUInfo((String) value);
157            break;
158        }
159        default: {
160            super.setParameter(key, value);
161        }
162        }
163    }
164
165    @Override
166    public Object getParameter(String key) {
167        JweHeaderKey headerKey = JweHeaderKey.getHeaderKey(key.toUpperCase());
168
169        Object value;
170
171        switch (headerKey) {
172        case ENC: {
173            value = getEncryptionMethod();
174            break;
175        }
176        case EPK: {
177            value = getEphemeralPublicKey();
178            break;
179        }
180        case ZIP: {
181            value = getCompressionAlgorithm();
182            break;
183        }
184        case APU: {
185            value = getAgreementPartyUInfo();
186            break;
187        }
188        default: {
189            value = super.getParameter(key);
190        }
191        }
192
193        return value;
194    }
195}