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