2 // Copyright © 2013-2018 Guy M. Allard
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
8 // http://www.apache.org/licenses/LICENSE-2.0
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
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
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"
56 srvCAFile
string // Name of file with broker's CA certificate, PEM format
60 ll
= log
.New(os
.Stdout
, "TLSU4 ", log
.Ldate|log
.Lmicroseconds|log
.Lshortfile
)
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.
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
,
83 ll
.Printf("%stag:%s connsess:%s main_using_cliCertFile:%s\n",
84 exampid
, tag
, sngecomm
.Lcs
,
86 ll
.Printf("%stag:%s connsess:%s main_using_cliKeyFile:%s\n",
87 exampid
, tag
, sngecomm
.Lcs
,
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)
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
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
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
)
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
)
138 ll
.Fatalf("%stag:%s connsess:%s main_on_connect error:%v",
139 exampid
, tag
, sngecomm
.Lcs
,
140 e
.Error()) // Handle this ......
144 sngecomm
.DumpTLSConfig(exampid
, tc
, nc
)
146 // *NOTE* application specific functionaltiy starts here!
148 // *NOTE* application specific functionaltiy ends here!
150 // Standard example disconnect sequence
151 e
= sngecomm
.CommonDisconnect(n
, conn
, exampid
, tag
, ll
)
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(),