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