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