1 #region Copyright notice and license 2 3 // Copyright 2015 gRPC authors. 4 // 5 // Licensed under the Apache License, Version 2.0 (the "License"); 6 // you may not use this file except in compliance with the License. 7 // You may obtain a copy of the License at 8 // 9 // http://www.apache.org/licenses/LICENSE-2.0 10 // 11 // Unless required by applicable law or agreed to in writing, software 12 // distributed under the License is distributed on an "AS IS" BASIS, 13 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 // See the License for the specific language governing permissions and 15 // limitations under the License. 16 17 #endregion 18 19 using System; 20 using System.Collections.Generic; 21 using Grpc.Core.Internal; 22 using Grpc.Core.Utils; 23 24 namespace Grpc.Core 25 { 26 /// <summary> 27 /// Server side credentials. 28 /// </summary> 29 public abstract class ServerCredentials 30 { 31 static readonly ServerCredentials InsecureInstance = new InsecureServerCredentialsImpl(); 32 33 /// <summary> 34 /// Returns instance of credential that provides no security and 35 /// will result in creating an unsecure server port with no encryption whatsoever. 36 /// </summary> 37 public static ServerCredentials Insecure 38 { 39 get 40 { 41 return InsecureInstance; 42 } 43 } 44 45 /// <summary> 46 /// Creates native object for the credentials. 47 /// </summary> 48 /// <returns>The native credentials.</returns> ToNativeCredentials()49 internal abstract ServerCredentialsSafeHandle ToNativeCredentials(); 50 51 private sealed class InsecureServerCredentialsImpl : ServerCredentials 52 { ToNativeCredentials()53 internal override ServerCredentialsSafeHandle ToNativeCredentials() 54 { 55 return null; 56 } 57 } 58 } 59 60 /// <summary> 61 /// Modes of requesting client's SSL certificate by the server. 62 /// Corresponds to <c>grpc_ssl_client_certificate_request_type</c>. 63 /// </summary> 64 public enum SslClientCertificateRequestType { 65 /// <summary> 66 /// Server does not request client certificate. 67 /// The certificate presented by the client is not checked by the server at 68 /// all. (A client may present a self signed or signed certificate or not 69 /// present a certificate at all and any of those option would be accepted) 70 /// </summary> 71 DontRequest = 0, 72 /// <summary> 73 /// Server requests client certificate but does not enforce that the client 74 /// presents a certificate. 75 /// If the client presents a certificate, the client authentication is left to 76 /// the application (the necessary metadata will be available to the 77 /// application via authentication context properties, see grpc_auth_context). 78 /// The client's key certificate pair must be valid for the SSL connection to 79 /// be established. 80 ///</summary> 81 RequestButDontVerify, 82 /// <summary> 83 /// Server requests client certificate but does not enforce that the client 84 /// presents a certificate. 85 /// If the client presents a certificate, the client authentication is done by 86 /// the gRPC framework. (For a successful connection the client needs to either 87 /// present a certificate that can be verified against the root certificate 88 /// configured by the server or not present a certificate at all) 89 /// The client's key certificate pair must be valid for the SSL connection to 90 /// be established. 91 /// </summary> 92 RequestAndVerify, 93 /// <summary> 94 /// Server requests client certificate and enforces that the client presents a 95 /// certificate. 96 /// If the client presents a certificate, the client authentication is left to 97 /// the application (the necessary metadata will be available to the 98 /// application via authentication context properties, see grpc_auth_context). 99 /// The client's key certificate pair must be valid for the SSL connection to 100 /// be established. 101 ///</summary> 102 RequestAndRequireButDontVerify, 103 /// <summary> 104 /// Server requests client certificate and enforces that the client presents a 105 /// certificate. 106 /// The certificate presented by the client is verified by the gRPC framework. 107 /// (For a successful connection the client needs to present a certificate that 108 /// can be verified against the root certificate configured by the server) 109 /// The client's key certificate pair must be valid for the SSL connection to 110 /// be established. 111 /// </summary> 112 RequestAndRequireAndVerify, 113 } 114 /// <summary> 115 /// Server-side SSL credentials. 116 /// </summary> 117 public class SslServerCredentials : ServerCredentials 118 { 119 readonly IList<KeyCertificatePair> keyCertificatePairs; 120 readonly string rootCertificates; 121 readonly SslClientCertificateRequestType clientCertificateRequest; 122 123 /// <summary> 124 /// Creates server-side SSL credentials. 125 /// </summary> 126 /// <param name="keyCertificatePairs">Key-certificates to use.</param> 127 /// <param name="rootCertificates">PEM encoded client root certificates used to authenticate client.</param> 128 /// <param name="forceClientAuth">Deprecated, use clientCertificateRequest overload instead.</param> SslServerCredentials(IEnumerable<KeyCertificatePair> keyCertificatePairs, string rootCertificates, bool forceClientAuth)129 public SslServerCredentials(IEnumerable<KeyCertificatePair> keyCertificatePairs, string rootCertificates, bool forceClientAuth) 130 : this(keyCertificatePairs, rootCertificates, forceClientAuth ? SslClientCertificateRequestType.RequestAndRequireAndVerify : SslClientCertificateRequestType.DontRequest) 131 { 132 } 133 134 /// <summary> 135 /// Creates server-side SSL credentials. 136 /// </summary> 137 /// <param name="keyCertificatePairs">Key-certificates to use.</param> 138 /// <param name="rootCertificates">PEM encoded client root certificates used to authenticate client.</param> 139 /// <param name="clientCertificateRequest">Options for requesting and verifying client certificate.</param> SslServerCredentials(IEnumerable<KeyCertificatePair> keyCertificatePairs, string rootCertificates, SslClientCertificateRequestType clientCertificateRequest)140 public SslServerCredentials(IEnumerable<KeyCertificatePair> keyCertificatePairs, string rootCertificates, SslClientCertificateRequestType clientCertificateRequest) 141 { 142 this.keyCertificatePairs = new List<KeyCertificatePair>(keyCertificatePairs).AsReadOnly(); 143 GrpcPreconditions.CheckArgument(this.keyCertificatePairs.Count > 0, 144 "At least one KeyCertificatePair needs to be provided."); 145 if (clientCertificateRequest == SslClientCertificateRequestType.RequestAndRequireAndVerify) 146 { 147 GrpcPreconditions.CheckNotNull(rootCertificates, 148 "Cannot require and verify client certificate unless you provide rootCertificates."); 149 } 150 this.rootCertificates = rootCertificates; 151 this.clientCertificateRequest = clientCertificateRequest; 152 } 153 154 /// <summary> 155 /// Creates server-side SSL credentials. 156 /// This constructor should be used if you do not wish to authenticate the client. 157 /// (client certificate won't be requested and checked by the server at all). 158 /// </summary> 159 /// <param name="keyCertificatePairs">Key-certificates to use.</param> SslServerCredentials(IEnumerable<KeyCertificatePair> keyCertificatePairs)160 public SslServerCredentials(IEnumerable<KeyCertificatePair> keyCertificatePairs) : this(keyCertificatePairs, null, SslClientCertificateRequestType.DontRequest) 161 { 162 } 163 164 /// <summary> 165 /// Key-certificate pairs. 166 /// </summary> 167 public IList<KeyCertificatePair> KeyCertificatePairs 168 { 169 get 170 { 171 return this.keyCertificatePairs; 172 } 173 } 174 175 /// <summary> 176 /// PEM encoded client root certificates. 177 /// </summary> 178 public string RootCertificates 179 { 180 get 181 { 182 return this.rootCertificates; 183 } 184 } 185 186 /// <summary> 187 /// Deprecated. If true, the authenticity of client check will be enforced. 188 /// </summary> 189 public bool ForceClientAuthentication 190 { 191 get 192 { 193 return this.clientCertificateRequest == SslClientCertificateRequestType.RequestAndRequireAndVerify; 194 } 195 } 196 197 /// <summary> 198 /// Mode of requesting certificate from client by the server. 199 /// </summary> 200 public SslClientCertificateRequestType ClientCertificateRequest 201 { 202 get 203 { 204 return this.clientCertificateRequest; 205 } 206 } 207 ToNativeCredentials()208 internal override ServerCredentialsSafeHandle ToNativeCredentials() 209 { 210 int count = keyCertificatePairs.Count; 211 string[] certChains = new string[count]; 212 string[] keys = new string[count]; 213 for (int i = 0; i < count; i++) 214 { 215 certChains[i] = keyCertificatePairs[i].CertificateChain; 216 keys[i] = keyCertificatePairs[i].PrivateKey; 217 } 218 return ServerCredentialsSafeHandle.CreateSslCredentials(rootCertificates, certChains, keys, clientCertificateRequest); 219 } 220 } 221 } 222