001/*
002 * oauth2-oidc-sdk
003 *
004 * Copyright 2012-2016, Connect2id Ltd and contributors.
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.openid.connect.sdk.id;
019
020
021import java.net.URI;
022import java.nio.charset.Charset;
023import java.nio.charset.StandardCharsets;
024import java.security.Provider;
025import java.util.Map;
026
027import com.nimbusds.oauth2.sdk.id.Subject;
028import net.jcip.annotations.ThreadSafe;
029
030
031/**
032 * Encoder and decoder of pairwise subject identifiers. The encoder algorithms
033 * must be deterministic, to ensure a given set of inputs always produces an
034 * identical pairwise subject identifier.
035 *
036 * <p>Decoding pairwise subject identifiers is optional, and is implemented by
037 * algorithms that supported reversal (typically with encryption-based codecs).
038 * Hash-based codecs don't support reversal.
039 *
040 * <p>Codec implementations thread-safe.
041 *
042 * <p>Related specifications:
043 *
044 * <ul>
045 *     <li>OpenID Connect Core 1.0, section 8.1.
046 * </ul>
047 */
048@ThreadSafe
049public abstract class PairwiseSubjectCodec {
050
051
052        /**
053         * The charset (UTF-8) for string to byte conversions.
054         */
055        public static final Charset CHARSET = StandardCharsets.UTF_8;
056
057
058        /**
059         * The salt.
060         */
061        private final byte[] salt;
062
063
064        /**
065         * The security provider.
066         */
067        private Provider provider;
068
069
070        /**
071         * Creates a new codec for pairwise subject identifiers.
072         *
073         * @param salt The salt, {@code null} if not required.
074         */
075        public PairwiseSubjectCodec(final byte[] salt) {
076
077                this.salt = salt;
078        }
079
080
081        /**
082         * Returns the salt.
083         *
084         * @return The salt, {@code null} if not required.
085         */
086        public byte[] getSalt() {
087                return salt;
088        }
089
090
091        /**
092         * Gets the security provider for cryptographic operations.
093         *
094         * @return The security provider, {@code null} if not specified
095         *         (implies the default one).
096         */
097        public Provider getProvider() {
098                return provider;
099        }
100
101
102        /**
103         * Sets the security provider for cryptographic operations.
104         *
105         * @param provider The security provider, {@code null} if not specified
106         *                 (implies the default one).
107         */
108        public void setProvider(final Provider provider) {
109                this.provider = provider;
110        }
111
112
113        /**
114         * Encodes a new pairwise subject identifier from the specified sector
115         * identifier URI and local subject.
116         *
117         * @param sectorURI The sector identifier URI. Its scheme should be
118         *                  "https", must include a host portion and must not
119         *                  be {@code null}.
120         * @param localSub  The local subject identifier. Must not be
121         *                  {@code null}.
122         *
123         * @return The pairwise subject identifier.
124         */
125        public Subject encode(final URI sectorURI, final Subject localSub) {
126
127                return encode(new SectorID(sectorURI), localSub);
128        }
129
130
131        /**
132         * Encodes a new pairwise subject identifier from the specified sector
133         * identifier and local subject.
134         *
135         * @param sectorID The sector identifier. Must not be
136         *                         {@code null}.
137         * @param localSub         The local subject identifier. Must not be
138         *                         {@code null}.
139         *
140         * @return The pairwise subject identifier.
141         */
142        public abstract Subject encode(final SectorID sectorID, final Subject localSub);
143
144
145        /**
146         * Decodes the specified pairwise subject identifier to produce the
147         * matching sector identifier and local subject. Throws a
148         * {@link UnsupportedOperationException}. Codecs that support pairwise
149         * subject identifier reversal should override this method.
150         *
151         * @param pairwiseSubject The pairwise subject identifier. Must be
152         *                        valid and not {@code null}.
153         *
154         * @return The matching sector identifier and local subject.
155         *
156         * @throws InvalidPairwiseSubjectException If the pairwise subject is
157         *                                         invalid.
158         */
159        public Map.Entry<SectorID,Subject> decode(final Subject pairwiseSubject)
160                throws InvalidPairwiseSubjectException {
161
162                throw new UnsupportedOperationException("Pairwise subject decoding is not supported");
163        }
164}