001package com.nimbusds.jose.jwk;
002
003
004import java.io.Serializable;
005
006import net.jcip.annotations.Immutable;
007
008import net.minidev.json.JSONAware;
009import net.minidev.json.JSONObject;
010
011import com.nimbusds.jose.Requirement;
012
013
014/**
015 * Key type. Represents the {@code kty} parameter in a JSON Web Key (JWK). 
016 * This class is immutable.
017 *
018 * <p>Includes constants for the following standard key types:
019 *
020 * <ul>
021 *     <li>{@link #EC}
022 *     <li>{@link #RSA}
023 *     <li>{@link #OCT}
024 * </ul>
025 *
026 * <p>Additional key types can be defined using the constructor.
027 *
028 * @author Vladimir Dzhuvinov
029 * @author Justin Richer
030 * @version 2013-05-29
031 */
032@Immutable
033public final class KeyType implements JSONAware, Serializable {
034
035
036        private static final long serialVersionUID = 1L;
037
038
039        /**
040         * The key type value.
041         */
042        private final String value;
043
044
045        /**
046         * The implementation requirement, {@code null} if not known.
047         */
048        private final Requirement requirement;
049
050
051        /**
052         * Elliptic Curve (DSS) key type (recommended).
053         */
054        public static final KeyType EC = new KeyType("EC", Requirement.RECOMMENDED);
055
056
057        /**
058         * RSA (RFC 3447) key type (required).
059         */
060        public static final KeyType RSA = new KeyType("RSA", Requirement.REQUIRED);
061
062
063        /**
064         * Octet sequence key type (optional)
065         */
066        public static final KeyType OCT = new KeyType("oct", Requirement.OPTIONAL);
067        
068
069        /**
070         * Creates a new key type with the specified value and implementation 
071         * requirement.
072         *
073         * @param value The key type value. Values are case sensitive. Must not
074         *              be {@code null}.
075         * @param req   The implementation requirement, {@code null} if not 
076         *              known.
077         */
078        public KeyType(final String value, final Requirement req) {
079
080                if (value == null) {
081
082                        throw new IllegalArgumentException("The key type value must not be null");
083                }
084
085                this.value = value;
086
087                requirement = req;
088        }
089
090
091        /**
092         * Gets the value of this key type. Values are case sensitive.
093         *
094         * @return The key type.
095         */
096        public String getValue() {
097
098                return value;
099        }
100
101
102        /**
103         * Gets the implementation requirement of this key type.
104         *
105         * @return The implementation requirement, {@code null} if not known.
106         */
107        public Requirement getRequirement() {
108
109                return requirement;
110        }
111
112
113        /**
114         * Overrides {@code Object.hashCode()}.
115         *
116         * @return The object hash code.
117         */
118        @Override
119        public int hashCode() {
120
121                return value.hashCode();
122        }
123
124
125        /**
126         * Overrides {@code Object.equals()}.
127         *
128         * @param object The object to compare to.
129         *
130         * @return {@code true} if the objects have the same value, otherwise
131         *         {@code false}.
132         */
133        @Override
134        public boolean equals(final Object object) {
135
136                return object != null && 
137                       object instanceof KeyType && 
138                       this.toString().equals(object.toString());
139        }
140
141
142        /**
143         * Returns the string representation of this key type.
144         *
145         * @see #getValue
146         *
147         * @return The string representation.
148         */
149        @Override
150        public String toString() {
151
152                return value;
153        }
154
155
156        /**
157         * Returns the JSON string representation of this key type.
158         * 
159         * @return The JSON string representation.
160         */
161        @Override
162        public String toJSONString() {
163
164                return "\"" + JSONObject.escape(value) + '"';
165        }
166
167
168        /**
169         * Parses a key type from the specified {@code kty} parameter value.
170         *
171         * @param s The string to parse. Must not be {@code null}.
172         *
173         * @return The key type (matching standard key type constant, else a 
174         *         newly created one).
175         */
176        public static KeyType parse(final String s) {
177
178                if (s.equals(EC.getValue())) {
179
180                        return EC;
181
182                } else if (s.equals(RSA.getValue())) {
183
184                        return RSA;
185
186                } else if (s.equals(OCT.getValue())) {
187
188                        return OCT;
189
190                } else {
191                        
192                        return new KeyType(s, null);
193                }
194        }
195}