summaryrefslogtreecommitdiffstats
path: root/docs/en/ranch/1.4/guide/ssl_auth/index.html
blob: 5420996618134a06d9a8275ab21487addbb0d350 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta name="description" content="">
    <meta name="author" content="Loïc Hoguin based on a design from (Soft10) Pol Cámara">

    <title>Nine Nines: SSL client authentication</title>

    <link href='https://fonts.googleapis.com/css?family=Open+Sans:400,700,400italic' rel='stylesheet' type='text/css'>
    <link href="/css/99s.css?r=1" rel="stylesheet">

    <link rel="shortcut icon" href="/img/ico/favicon.ico">
    <link rel="apple-touch-icon-precomposed" sizes="114x114" href="/img/ico/apple-touch-icon-114.png">
    <link rel="apple-touch-icon-precomposed" sizes="72x72" href="/img/ico/apple-touch-icon-72.png">
    <link rel="apple-touch-icon-precomposed" href="/img/ico/apple-touch-icon-57.png">

    
</head>


<body class="">
  <header id="page-head">
    <div id="topbar" class="container">
        <div class="row">
          <div class="span2">
            <h1 id="logo"><a href="/" title="99s">99s</a></h1>
          </div>
          <div class="span10">
            
            <div id="side-header">
              <nav>
                <ul>
                  <li><a title="Hear my thoughts" href="/articles">Articles</a></li>
  				  <li><a title="Watch my talks" href="/talks">Talks</a></li>
  				  <li class="active"><a title="Read the docs" href="/docs">Documentation</a></li>
  				  <li><a title="Request my services" href="/services">Consulting & Training</a></li>
                </ul>
              </nav> 
              <ul id="social">
                <li>
                  <a href="https://github.com/ninenines" title="Check my Github repositories"><img src="/img/ico_github.png" data-hover="/img/ico_github_alt.png" alt="Github"></a>
                </li>
                    <li>
						<a title="Contact me" href="mailto:[email protected]"><img src="/img/ico_mail.png" data-hover="/img/ico_mail_alt.png"></a>
					</li>
              </ul>
            </div>
          </div>
        </div>
    </div>


</header>

<div id="contents" class="two_col">
<div class="container">
<div class="row">
<div id="docs" class="span9 maincol">

<h1 class="lined-header"><span>SSL client authentication</span></h1>

<h2 id="_purpose">Purpose</h2>
<p>SSL client authentication is a mechanism allowing applications to identify certificates. This allows your application to make sure that the client is an authorized certificate, but makes no claim about whether the user can be trusted. This can be combined with a password based authentication to attain greater security.</p>
<p>The server only needs to retain the certificate serial number and the certificate issuer to authenticate the certificate. Together, they can be used to uniquely identify a certicate.</p>
<p>As Ranch allows the same protocol code to be used for both SSL and non-SSL transports, you need to make sure you are in an SSL context before attempting to perform an SSL client authentication. This can be done by checking the return value of <code>Transport:name/0</code>.</p>
<h2 id="_obtaining_client_certificates">Obtaining client certificates</h2>
<p>You can obtain client certificates from various sources. You can generate them yourself, or you can use a service like CAcert.org which allows you to generate client and server certificates for free.</p>
<p>Following are the steps you need to take to create a CAcert.org account, generate a certificate and install it in your favorite browser.</p>
<ul><li>Open <a href="http://cacert.org">http://cacert.org</a> in your favorite browser
</li>
<li>Root Certificate link: install both certificates
</li>
<li>Join (Register an account)
</li>
<li>Verify your account (check your email inbox!)
</li>
<li>Log in
</li>
<li>Client Certificates: New
</li>
<li>Follow instructions to create the certificate
</li>
<li>Install the certificate in your browser
</li>
</ul>
<p>You can optionally save the certificate for later use, for example to extract the <code>IssuerID</code> information as will be detailed later on.</p>
<h2 id="_transport_configuration">Transport configuration</h2>
<p>The SSL transport does not request a client certificate by default. You need to specify the <code>{verify, verify_peer}</code> option when starting the listener to enable this behavior.</p>
<div class="listingblock"><div class="title">Configure a listener for SSL authentication</div>
<div class="content"><!-- Generator: GNU source-highlight 3.1.8
by Lorenzo Bettini
http://www.lorenzobettini.it
http://www.gnu.org/software/src-highlite -->
<pre><tt>{<font color="#FF6600">ok</font>, <font color="#990000">_</font>} <font color="#990000">=</font> <b><font color="#000000">ranch:start_listener</font></b>(<font color="#FF6600">my_ssl</font>,
	<font color="#FF6600">ranch_ssl</font>, [
		{<font color="#FF6600">port</font>, <font color="#009900">SSLPort</font>},
		{<font color="#FF6600">certfile</font>, <font color="#009900">PathToCertfile</font>},
		{<font color="#FF6600">cacertfile</font>, <font color="#009900">PathToCACertfile</font>},
		{<font color="#FF6600">verify</font>, <font color="#FF6600">verify_peer</font>}
	],
	<font color="#FF6600">my_protocol</font>, []
)<font color="#990000">.</font></tt></pre>
</div></div>
<p>In this example we set the required <code>port</code> and <code>certfile</code>, but also the <code>cacertfile</code> containing the CACert.org root certificate, and the option to request the client certificate.</p>
<p>If you enable the <code>{verify, verify_peer}</code> option and the client does not have a client certificate configured for your domain, then no certificate will be sent. This allows you to use SSL for more than just authenticated clients.</p>
<h2 id="_authentication">Authentication</h2>
<p>To authenticate users, you must first save the certificate information required. If you have your users&apos; certificate files, you can simply load the certificate and retrieve the information directly.</p>
<div class="listingblock"><div class="title">Retrieve the issuer ID from a certificate</div>
<div class="content"><!-- Generator: GNU source-highlight 3.1.8
by Lorenzo Bettini
http://www.lorenzobettini.it
http://www.gnu.org/software/src-highlite -->
<pre><tt><b><font color="#000000">certfile_to_issuer_id</font></b>(<font color="#009900">Filename</font>) <font color="#990000">-&gt;</font>
	{<font color="#FF6600">ok</font>, <font color="#009900">Data</font>} <font color="#990000">=</font> <b><font color="#000000">file:read_file</font></b>(<font color="#009900">Filename</font>),
	[{<font color="#FF6600">'Certificate'</font>, <font color="#009900">Cert</font>, <font color="#FF6600">not_encrypted</font>}] <font color="#990000">=</font> <b><font color="#000000">public_key:pem_decode</font></b>(<font color="#009900">Data</font>),
	{<font color="#FF6600">ok</font>, <font color="#009900">IssuerID</font>} <font color="#990000">=</font> <b><font color="#000000">public_key:pkix_issuer_id</font></b>(<font color="#009900">Cert</font>, <b><font color="#000080">self</font></b>),
	<font color="#009900">IssuerID</font><font color="#990000">.</font></tt></pre>
</div></div>
<p>The <code>IssuerID</code> variable contains both the certificate serial number and the certificate issuer stored in a tuple, so this value alone can be used to uniquely identify the user certificate. You can save this value in a database, a configuration file or any other place where an Erlang term can be stored and retrieved.</p>
<p>To retrieve the <code>IssuerID</code> from a running connection, you need to first retrieve the client certificate and then extract this information from it. Ranch does not provide a function to retrieve the client certificate. Instead you can use the <code>ssl:peercert/1</code> function. Once you have the certificate, you can again use the <code>public_key:pkix_issuer_id/2</code> to extract the <code>IssuerID</code> value.</p>
<p>The following function returns the <code>IssuerID</code> or <code>false</code> if no client certificate was found. This snippet is intended to be used from your protocol code.</p>
<div class="listingblock"><div class="title">Retrieve the issuer ID from the certificate for the current connection</div>
<div class="content"><!-- Generator: GNU source-highlight 3.1.8
by Lorenzo Bettini
http://www.lorenzobettini.it
http://www.gnu.org/software/src-highlite -->
<pre><tt><b><font color="#000000">socket_to_issuer_id</font></b>(<font color="#009900">Socket</font>) <font color="#990000">-&gt;</font>
	<b><font color="#0000FF">case</font></b> <b><font color="#000000">ssl:peercert</font></b>(<font color="#009900">Socket</font>) <b><font color="#0000FF">of</font></b>
		{<font color="#FF6600">error</font>, <font color="#FF6600">no_peercert</font>} <font color="#990000">-&gt;</font>
			<font color="#000080">false</font>;
		{<font color="#FF6600">ok</font>, <font color="#009900">Cert</font>} <font color="#990000">-&gt;</font>
			{<font color="#FF6600">ok</font>, <font color="#009900">IssuerID</font>} <font color="#990000">=</font> <b><font color="#000000">public_key:pkix_issuer_id</font></b>(<font color="#009900">Cert</font>, <b><font color="#000080">self</font></b>),
			<font color="#009900">IssuerID</font>
	<b><font color="#0000FF">end</font></b><font color="#990000">.</font></tt></pre>
</div></div>
<p>You then only need to match the <code>IssuerID</code> value to authenticate the user.</p>




	
		
		
		
		
		

		<nav style="margin:1em 0">
			
				<a style="float:left" href="https://ninenines.eu/docs/en/ranch/1.4/guide/parsers/">
					Writing parsers
				</a>
			

			
				<a style="float:right" href="https://ninenines.eu/docs/en/ranch/1.4/guide/internals/">
					Internals
				</a>
			
		</nav>
	



</div>

<div class="span3 sidecol">


<h3>
	Ranch
	1.4
	
	User Guide
</h3>

<ul>
	
		<li><a href="/docs/en/ranch/1.4/guide">User Guide</a></li>
	
	
		<li><a href="/docs/en/ranch/1.4/manual">Function Reference</a></li>
	
	
</ul>

<h4 id="docs-nav">Navigation</h4>

<h4>Version select</h4>
<ul>
	
	
	
		<li><a href="/docs/en/ranch/1.5/guide">1.5</a></li>
	
		<li><a href="/docs/en/ranch/1.4/guide">1.4</a></li>
	
		<li><a href="/docs/en/ranch/1.3/guide">1.3</a></li>
	
		<li><a href="/docs/en/ranch/1.2/guide">1.2</a></li>
	
</ul>

</div>
</div>
</div>
</div>

      <footer>
        <div class="container">
          <div class="row">
            <div class="span6">
              <p id="scroll-top"><a href="#">↑ Scroll to top</a></p>
              <nav>
                <ul>
                  <li><a href="mailto:[email protected]" title="Contact us">Contact us</a></li><li><a href="https://github.com/ninenines/ninenines.github.io" title="Github repository">Contribute to this site</a></li>
                </ul>
              </nav>
            </div>
            <div class="span6 credits">
               <p><img src="/img/footer_logo.png"></p>
               <p>Copyright &copy; Loïc Hoguin 2012-2018</p>
            </div>
          </div>
        </div>
      </footer>

    
    <script src="/js/custom.js"></script>
  </body>
</html>