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