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