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.oauth2.sdk.auth;
019
020
021import com.nimbusds.jose.util.Base64URL;
022import com.nimbusds.jose.util.X509CertUtils;
023import com.nimbusds.jwt.JWTClaimsSet;
024import com.nimbusds.oauth2.sdk.ParseException;
025import com.nimbusds.oauth2.sdk.cnf.AbstractConfirmation;
026import com.nimbusds.oauth2.sdk.util.JSONObjectUtils;
027import net.jcip.annotations.Immutable;
028import net.minidev.json.JSONObject;
029
030import java.security.cert.X509Certificate;
031import java.util.AbstractMap;
032import java.util.Map;
033import java.util.Objects;
034
035
036/**
037 * X.509 certificate SHA-256 confirmation.
038 */
039@Immutable
040public final class X509CertificateConfirmation extends AbstractConfirmation {
041        
042        
043        /**
044         * The X.509 certificate SHA-256 thumbprint.
045         */
046        private final Base64URL x5tS256;
047        
048        
049        /**
050         * Creates a new X.509 certificate SHA-256 confirmation.
051         *
052         * @param x5tS256 The X.509 certificate SHA-256 thumbprint. Must not
053         *                be {@code null}.
054         */
055        public X509CertificateConfirmation(final Base64URL x5tS256) {
056                this.x5tS256 = Objects.requireNonNull(x5tS256);
057        }
058        
059        
060        /**
061         * Returns the X.509 certificate SHA-256 thumbprint.
062         *
063         * @return The X.509 certificate SHA-256 thumbprint.
064         */
065        public Base64URL getValue() {
066                
067                return x5tS256;
068        }
069        
070        
071        @Override
072        public Map.Entry<String,JSONObject> toJWTClaim() {
073                
074                JSONObject cnf = new JSONObject();
075                cnf.put("x5t#S256", x5tS256.toString());
076                
077                return new AbstractMap.SimpleImmutableEntry<>(
078                        "cnf",
079                        cnf
080                );
081        }
082        
083        
084        @Override
085        public boolean equals(Object o) {
086                if (this == o) return true;
087                if (!(o instanceof X509CertificateConfirmation)) return false;
088                X509CertificateConfirmation that = (X509CertificateConfirmation) o;
089                return x5tS256.equals(that.x5tS256);
090        }
091        
092        
093        @Override
094        public int hashCode() {
095                return Objects.hash(x5tS256);
096        }
097        
098        
099        /**
100         * Parses an X.509 certificate confirmation from the specified JWT
101         * claims set.
102         *
103         * @param jwtClaimsSet The JWT claims set.
104         *
105         * @return The X.509 certificate confirmation, {@code null} if not
106         *         found.
107         */
108        public static X509CertificateConfirmation parse(final JWTClaimsSet jwtClaimsSet) {
109                
110                JSONObject cnf = parseConfirmationJSONObject(jwtClaimsSet);
111                
112                if (cnf == null) {
113                        return null;
114                }
115                
116                return parseFromConfirmationJSONObject(cnf);
117        }
118        
119        
120        /**
121         * Parses an X.509 certificate confirmation from the specified JSON
122         * object representation of a JWT claims set.
123         *
124         * @param jsonObject The JSON object.
125         *
126         * @return The X.509 certificate confirmation, {@code null} if not
127         *         found.
128         */
129        public static X509CertificateConfirmation parse(final JSONObject jsonObject) {
130                
131                if (! jsonObject.containsKey("cnf")) {
132                        return null;
133                }
134                
135                try {
136                        return parseFromConfirmationJSONObject(JSONObjectUtils.getJSONObject(jsonObject, "cnf"));
137                } catch (ParseException e) {
138                        return null;
139                }
140        }
141        
142        
143        /**
144         * Parses an X.509 certificate confirmation from the specified
145         * confirmation ("cnf") JSON object.
146         *
147         * @param cnf The confirmation JSON object, {@code null} if none.
148         *
149         * @return The X.509 certificate confirmation, {@code null} if not
150         *         found.
151         */
152        public static X509CertificateConfirmation parseFromConfirmationJSONObject(final JSONObject cnf) {
153                
154                if (cnf == null) {
155                        return null;
156                }
157                
158                try {
159                        String x5tString = JSONObjectUtils.getNonBlankString(cnf, "x5t#S256");
160                        return new X509CertificateConfirmation(new Base64URL(x5tString));
161                        
162                } catch (ParseException e) {
163                        return null;
164                }
165        }
166        
167        
168        /**
169         * Creates a confirmation of the specified X.509 certificate.
170         *
171         * @param x509Cert The X.509 certificate.
172         *
173         * @return The X.509 certificate confirmation.
174         */
175        public static X509CertificateConfirmation of(final X509Certificate x509Cert) {
176                
177                return new X509CertificateConfirmation(X509CertUtils.computeSHA256Thumbprint(x509Cert));
178        }
179}