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}