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.oauth2.sdk.ParseException; 022import com.nimbusds.oauth2.sdk.http.HTTPRequest; 023import com.nimbusds.oauth2.sdk.id.ClientID; 024import com.nimbusds.oauth2.sdk.util.MultivaluedMapUtils; 025import com.nimbusds.oauth2.sdk.util.StringUtils; 026import net.jcip.annotations.Immutable; 027 028import javax.net.ssl.SSLSocketFactory; 029import java.security.cert.X509Certificate; 030import java.util.List; 031import java.util.Map; 032import java.util.Objects; 033 034 035/** 036 * PKI mutual TLS client authentication at the Token endpoint. The client 037 * certificate is PKI bound, as opposed to 038 * {@link SelfSignedTLSClientAuthentication self_signed_tls_client_auth} which 039 * relies on a self-signed certificate. Implements 040 * {@link ClientAuthenticationMethod#TLS_CLIENT_AUTH}. 041 * 042 * <p>Related specifications: 043 * 044 * <ul> 045 * <li>OAuth 2.0 Mutual TLS Client Authentication and Certificate Bound 046 * Access Tokens (RFC 8705) 047 * </ul> 048 */ 049@Immutable 050public class PKITLSClientAuthentication extends TLSClientAuthentication { 051 052 053 /** 054 * The client X.509 certificate subject DN. 055 */ 056 private final String certSubjectDN; 057 058 059 /** 060 * Creates a new PKI mutual TLS client authentication. This constructor 061 * is intended for an outgoing token request. 062 * 063 * @param clientID The client identifier. Must not be 064 * {@code null}. 065 * @param sslSocketFactory The SSL socket factory to use for the 066 * outgoing HTTPS request and to present the 067 * client certificate(s), {@code null} to use 068 * the default one. 069 */ 070 public PKITLSClientAuthentication(final ClientID clientID, 071 final SSLSocketFactory sslSocketFactory) { 072 073 super(ClientAuthenticationMethod.TLS_CLIENT_AUTH, clientID, sslSocketFactory); 074 certSubjectDN = null; 075 } 076 077 078 /** 079 * Creates a new PKI mutual TLS client authentication. This constructor 080 * is intended for a received token request. 081 * 082 * @param clientID The client identifier. Must not be 083 * {@code null}. 084 * @param certSubjectDN The subject DN of the received validated client 085 * X.509 certificate. Must not be {@code null}. 086 * @deprecated This constructor does set the certificate 087 */ 088 @Deprecated 089 public PKITLSClientAuthentication(final ClientID clientID, 090 final String certSubjectDN) { 091 092 super(ClientAuthenticationMethod.TLS_CLIENT_AUTH, clientID, (X509Certificate) null); 093 this.certSubjectDN = Objects.requireNonNull(certSubjectDN); 094 } 095 096 097 /** 098 * Creates a new PKI mutual TLS client authentication. This constructor 099 * is intended for a received token request. 100 * 101 * @param clientID The client identifier. Must not be {@code null}. 102 * @param certificate The validated client X.509 certificate from the 103 * received HTTPS request. Must not be {@code null}. 104 */ 105 public PKITLSClientAuthentication(final ClientID clientID, 106 final X509Certificate certificate) { 107 108 super(ClientAuthenticationMethod.TLS_CLIENT_AUTH, clientID, certificate); 109 this.certSubjectDN = certificate.getSubjectX500Principal().getName(); 110 } 111 112 113 /** 114 * Gets the subject DN of the received validated client X.509 115 * certificate. 116 * 117 * @return The subject DN. 118 */ 119 public String getClientX509CertificateSubjectDN() { 120 121 return certSubjectDN; 122 } 123 124 125 /** 126 * Parses a PKI mutual TLS client authentication from the specified 127 * HTTP request. 128 * 129 * @param httpRequest The HTTP request to parse. Must not be 130 * {@code null} and must include a validated client 131 * X.509 certificate. 132 * 133 * @return The PKI mutual TLS client authentication. 134 * 135 * @throws ParseException If the {@code client_id} or client X.509 136 * certificate is missing. 137 */ 138 public static PKITLSClientAuthentication parse(final HTTPRequest httpRequest) 139 throws ParseException { 140 141 Map<String,List<String>> params = httpRequest.getBodyAsFormParameters(); 142 143 String clientIDString = MultivaluedMapUtils.getFirstValue(params, "client_id"); 144 145 if (StringUtils.isBlank(clientIDString)) { 146 throw new ParseException("Missing client_id parameter"); 147 } 148 149 if (httpRequest.getClientX509Certificate() == null) { 150 throw new ParseException("Missing client X.509 certificate"); 151 } 152 153 return new PKITLSClientAuthentication( 154 new ClientID(clientIDString), 155 httpRequest.getClientX509Certificate() 156 ); 157 } 158}