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}