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.util.Map; 022import javax.net.ssl.SSLSocketFactory; 023 024import com.nimbusds.oauth2.sdk.ParseException; 025import com.nimbusds.oauth2.sdk.http.HTTPRequest; 026import com.nimbusds.oauth2.sdk.id.ClientID; 027import com.nimbusds.oauth2.sdk.util.URLUtils; 028import net.jcip.annotations.Immutable; 029import org.apache.commons.lang3.StringUtils; 030 031 032/** 033 * TLS / X.509 certificate client authentication at the Token endpoint. The 034 * client certificate is PKI bound, as opposed to 035 * {@link PublicKeyTLSClientAuthentication pub_key_tls_client_auth} which 036 * relies on direct public key binding. Implements 037 * {@link ClientAuthenticationMethod#TLS_CLIENT_AUTH}. 038 * 039 * <p>Related specifications: 040 * 041 * <ul> 042 * <li>Mutual TLS Profile for OAuth 2.0 (draft-ietf-oauth-mtls-03), section 043 * 2.1. 044 * </ul> 045 */ 046@Immutable 047public class TLSClientAuthentication extends AbstractTLSClientAuthentication { 048 049 050 /** 051 * The client X.509 certificate subject DN. 052 */ 053 private final String certSubjectDN; 054 055 056 /** 057 * The client X.509 certificate root DN, {@code null} if not specified. 058 */ 059 private final String certRootDN; 060 061 062 /** 063 * Creates a new TLS / X.509 certificate client authentication. This 064 * constructor is intended for an outgoing token request. 065 * 066 * @param clientID The client identifier. Must not be 067 * {@code null}. 068 * @param sslSocketFactory The SSL socket factory to use for the 069 * outgoing HTTPS request and to present the 070 * client certificate(s), {@code null} to use 071 * the default one. 072 */ 073 public TLSClientAuthentication(final ClientID clientID, 074 final SSLSocketFactory sslSocketFactory) { 075 076 super(ClientAuthenticationMethod.TLS_CLIENT_AUTH, clientID, sslSocketFactory); 077 certSubjectDN = null; 078 certRootDN = null; 079 } 080 081 082 /** 083 * Creates a new TLS / X.509 certificate client authentication. This 084 * constructor is intended for a received token request. 085 * 086 * @param clientID The client identifier. Must not be 087 * {@code null}. 088 * @param certSubjectDN The subject DN of the received validated client 089 * X.509 certificate. Must not be {@code null}. 090 * @param certRootDN The root issuer DN of the received validated 091 * client X.509 certificate, {@code null} if not 092 * specified. 093 */ 094 public TLSClientAuthentication(final ClientID clientID, 095 final String certSubjectDN, 096 final String certRootDN) { 097 098 super(ClientAuthenticationMethod.TLS_CLIENT_AUTH, clientID); 099 100 if (certSubjectDN == null) { 101 throw new IllegalArgumentException("The X.509 client certificate subject DN must not be null"); 102 } 103 this.certSubjectDN = certSubjectDN; 104 105 this.certRootDN = certRootDN; 106 } 107 108 109 /** 110 * Gets the subject DN of the received validated client X.509 111 * certificate. 112 * 113 * @return The subject DN. 114 */ 115 public String getClientX509CertificateSubjectDN() { 116 117 return certSubjectDN; 118 } 119 120 121 /** 122 * Gets the root issuer DN of the received validated client X.509 123 * certificate. 124 * 125 * @return The root DN, {@code null} if not specified. 126 */ 127 public String getClientX509CertificateRootDN() { 128 129 return certRootDN; 130 } 131 132 133 /** 134 * Parses a TLS / X.509 certificate client authentication from the 135 * specified HTTP request. 136 * 137 * @param httpRequest The HTTP request to parse. Must not be 138 * {@code null} and must include a validated client 139 * X.509 certificate. 140 * 141 * @return The TLS / X.509 certificate client authentication. 142 * 143 * @throws ParseException If the {@code client_id} or client X.509 144 * certificate is missing. 145 */ 146 public static TLSClientAuthentication parse(final HTTPRequest httpRequest) 147 throws ParseException { 148 149 String query = httpRequest.getQuery(); 150 151 if (query == null) { 152 throw new ParseException("Missing HTTP POST request entity body"); 153 } 154 155 Map<String,String> params = URLUtils.parseParameters(query); 156 157 String clientIDString = params.get("client_id"); 158 159 if (StringUtils.isBlank(clientIDString)) { 160 throw new ParseException("Missing client_id parameter"); 161 } 162 163 if (httpRequest.getClientX509CertificateSubjectDN() == null) { 164 throw new ParseException("Missing client X.509 certificate subject DN"); 165 } 166 167 return new TLSClientAuthentication( 168 new ClientID(clientIDString), 169 httpRequest.getClientX509CertificateSubjectDN(), 170 httpRequest.getClientX509CertificateRootDN()); 171 } 172}