Copyright date updates.
[stompngo_examples.git] / tlsexamps / tlsuc4 / tlsuc4.go
blobf500a6df2369e861416450539117c1ff02ad4c26
1 //
2 // Copyright © 2013-2018 Guy M. Allard
3 //
4 // Licensed under the Apache License, Version 2.0 (the "License");
5 // you may not use this file except in compliance with the License.
6 // You may obtain a copy of the License at
7 //
8 // http://www.apache.org/licenses/LICENSE-2.0
9 //
10 // Unless required by applicable law or agreed to in writing, software
11 // distributed under the License is distributed on an "AS IS" BASIS,
12 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 // See the License for the specific language governing permissions and
14 // limitations under the License.
18 Connect and Disconnect from a STOMP broker with a TLS connection, use case 4.
20 TLS Use Case 4 - broker *does* authenticate client, client *does* authenticate broker
22 Subcase 4.A - Message broker configuration does *not* require client authentication
24 - Expect connection success
26 Subcase 4.B - Message broker configuration *does* require client authentication
28 - Expect connection success if the broker can authenticate the client certificate
30 Example use might be:
32 go build
33 STOMP_PORT=61611 ./tlsuc4 -srvCAFile=/ad3/gma/sslwork/2016-02/ca.crt -cliCertFile=/ad3/gma/sslwork/2016-02/client.crt -cliKeyFile=/ad3/gma/sslwork/2016-02/client.key
36 package main
38 import (
39 "crypto/tls"
40 "crypto/x509"
41 "encoding/pem"
42 "flag"
43 "io/ioutil"
44 "log"
45 "os"
46 "time"
47 // senv methods could be used in general by stompngo clients.
48 "github.com/gmallard/stompngo/senv"
49 // sngecomm methods are used specifically for these example clients.
50 "github.com/gmallard/stompngo_examples/sngecomm"
53 var (
54 exampid = "tlsuc4:"
55 tc *tls.Config
56 srvCAFile string // Name of file with broker's CA certificate, PEM format
57 cliCertFile string
58 cliKeyFile string
60 ll = log.New(os.Stdout, "TLSU4 ", log.Ldate|log.Lmicroseconds|log.Lshortfile)
62 tag = "tuc4main"
65 func init() {
66 flag.StringVar(&srvCAFile, "srvCAFile", "DUMMY", "Name of file with broker CA certificate")
67 flag.StringVar(&cliCertFile, "cliCertFile", "DUMMY_CERT", "Name of client cert file")
68 flag.StringVar(&cliKeyFile, "cliKeyFile", "DUMMY_KEY", "Name of client key file")
71 // Connect to a STOMP broker using TLS and disconnect.
72 func main() {
74 st := time.Now()
76 ll.Printf("%stag:%s connsess:%s starts\n",
77 exampid, tag, sngecomm.Lcs)
79 flag.Parse() // Parse flags
80 ll.Printf("%stag:%s connsess:%s main_using_srvCAFile:%s\n",
81 exampid, tag, sngecomm.Lcs,
82 srvCAFile)
83 ll.Printf("%stag:%s connsess:%s main_using_cliCertFile:%s\n",
84 exampid, tag, sngecomm.Lcs,
85 cliCertFile)
86 ll.Printf("%stag:%s connsess:%s main_using_cliKeyFile:%s\n",
87 exampid, tag, sngecomm.Lcs,
88 cliKeyFile)
90 // TLS Configuration.
91 tc = new(tls.Config)
92 tc.InsecureSkipVerify = false // *Do* check the broker's certificate
93 // Be polite, allow SNI (Server Virtual Hosting)
94 tc.ServerName = senv.Host()
95 // Finish TLS Config initialization, so client can authenticate broker,
96 // and broker can authenticate client.
98 // Usually one will use the default cipher suites that go provides.
99 // However, if a custom cipher squite list is needed/required this
100 // is how it is accomplished.
101 if sngecomm.UseCustomCiphers() { // Set custom cipher suite list
102 tc.CipherSuites = append(tc.CipherSuites, sngecomm.CustomCiphers()...)
105 b, e := ioutil.ReadFile(srvCAFile) // Read broker's CA cert (PEM)
106 if e != nil {
107 ll.Fatalf("%stag:%s connsess:%s main_read_file error:%v",
108 exampid, tag, sngecomm.Lcs,
109 e.Error()) // Handle this ......
111 k, _ := pem.Decode(b) // Decode PEM format
112 if k == nil {
113 ll.Fatalf("%stag:%s connsess:%s main_decode error:%v",
114 exampid, tag, sngecomm.Lcs,
115 e.Error()) // Handle this ......
118 c, e := x509.ParseCertificate(k.Bytes) // Create *x509.Certificate
119 if e != nil {
120 ll.Fatalf("%stag:%s connsess:%s main_parse_cert error:%v",
121 exampid, tag, sngecomm.Lcs,
122 e.Error()) // Handle this ......
124 tc.RootCAs = x509.NewCertPool() // Create a cert "pool"
125 tc.RootCAs.AddCert(c) // Add the CA cert to the pool
126 // Finish TLS Config initialization, so broker can authenticate client.
127 cc, e := tls.LoadX509KeyPair(cliCertFile, cliKeyFile)
128 if e != nil {
129 ll.Fatalf("%s %s\n", exampid, e.Error()) // Handle this ......
131 tc.Certificates = append(tc.Certificates, cc) // Add cert
132 // This is OK, but does not seem to be required
133 tc.BuildNameToCertificate() // Build names map
135 // Standard example TLS connect sequence
136 n, conn, e := sngecomm.CommonTLSConnect(exampid, tag, ll, tc)
137 if e != nil {
138 ll.Fatalf("%stag:%s connsess:%s main_on_connect error:%v",
139 exampid, tag, sngecomm.Lcs,
140 e.Error()) // Handle this ......
143 nc := n.(*tls.Conn)
144 sngecomm.DumpTLSConfig(exampid, tc, nc)
146 // *NOTE* application specific functionaltiy starts here!
147 // For you to add.
148 // *NOTE* application specific functionaltiy ends here!
150 // Standard example disconnect sequence
151 e = sngecomm.CommonDisconnect(n, conn, exampid, tag, ll)
152 if e != nil {
153 ll.Fatalf("%s %s\n", exampid, e.Error()) // Handle this ......
156 ll.Printf("%stag:%s connsess:%s main_elapsed:%v\n",
157 exampid, tag, conn.Session(),
158 time.Now().Sub(st))