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     /// Server-side SSL credentials.
62     /// </summary>
63     public class SslServerCredentials : ServerCredentials
64     {
65         readonly IList<KeyCertificatePair> keyCertificatePairs;
66         readonly string rootCertificates;
67         readonly bool forceClientAuth;
68 
69         /// <summary>
70         /// Creates server-side SSL credentials.
71         /// </summary>
72         /// <param name="keyCertificatePairs">Key-certificates to use.</param>
73         /// <param name="rootCertificates">PEM encoded client root certificates used to authenticate client.</param>
74         /// <param name="forceClientAuth">If true, client will be rejected unless it proves its unthenticity using against rootCertificates.</param>
SslServerCredentials(IEnumerable<KeyCertificatePair> keyCertificatePairs, string rootCertificates, bool forceClientAuth)75         public SslServerCredentials(IEnumerable<KeyCertificatePair> keyCertificatePairs, string rootCertificates, bool forceClientAuth)
76         {
77             this.keyCertificatePairs = new List<KeyCertificatePair>(keyCertificatePairs).AsReadOnly();
78             GrpcPreconditions.CheckArgument(this.keyCertificatePairs.Count > 0,
79                 "At least one KeyCertificatePair needs to be provided.");
80             if (forceClientAuth)
81             {
82                 GrpcPreconditions.CheckNotNull(rootCertificates,
83                     "Cannot force client authentication unless you provide rootCertificates.");
84             }
85             this.rootCertificates = rootCertificates;
86             this.forceClientAuth = forceClientAuth;
87         }
88 
89         /// <summary>
90         /// Creates server-side SSL credentials.
91         /// This constructor should be use if you do not wish to autheticate client
92         /// using client root certificates.
93         /// </summary>
94         /// <param name="keyCertificatePairs">Key-certificates to use.</param>
SslServerCredentials(IEnumerable<KeyCertificatePair> keyCertificatePairs)95         public SslServerCredentials(IEnumerable<KeyCertificatePair> keyCertificatePairs) : this(keyCertificatePairs, null, false)
96         {
97         }
98 
99         /// <summary>
100         /// Key-certificate pairs.
101         /// </summary>
102         public IList<KeyCertificatePair> KeyCertificatePairs
103         {
104             get
105             {
106                 return this.keyCertificatePairs;
107             }
108         }
109 
110         /// <summary>
111         /// PEM encoded client root certificates.
112         /// </summary>
113         public string RootCertificates
114         {
115             get
116             {
117                 return this.rootCertificates;
118             }
119         }
120 
121         /// <summary>
122         /// If true, the authenticity of client check will be enforced.
123         /// </summary>
124         public bool ForceClientAuthentication
125         {
126             get
127             {
128                 return this.forceClientAuth;
129             }
130         }
131 
ToNativeCredentials()132         internal override ServerCredentialsSafeHandle ToNativeCredentials()
133         {
134             int count = keyCertificatePairs.Count;
135             string[] certChains = new string[count];
136             string[] keys = new string[count];
137             for (int i = 0; i < count; i++)
138             {
139                 certChains[i] = keyCertificatePairs[i].CertificateChain;
140                 keys[i] = keyCertificatePairs[i].PrivateKey;
141             }
142             return ServerCredentialsSafeHandle.CreateSslCredentials(rootCertificates, certChains, keys, forceClientAuth);
143         }
144     }
145 }
146