2 // Copyright © 2013-2016 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 ./tlsuc4 -srvCAFile=/ad3/gma/sslwork/2013/TestCA.crt -cliCertFile=/ad3/gma/sslwork/2013/client.crt -cliKeyFile=/ad3/gma/sslwork/2013/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.
97 b
, e
:= ioutil
.ReadFile(srvCAFile
) // Read broker's CA cert (PEM)
99 ll
.Fatalf("%stag:%s connsess:%s main_read_file error:%v",
100 exampid
, tag
, sngecomm
.Lcs
,
101 e
.Error()) // Handle this ......
103 k
, _
:= pem
.Decode(b
) // Decode PEM format
105 ll
.Fatalf("%stag:%s connsess:%s main_decode error:%v",
106 exampid
, tag
, sngecomm
.Lcs
,
107 e
.Error()) // Handle this ......
110 c
, e
:= x509
.ParseCertificate(k
.Bytes
) // Create *x509.Certificate
112 ll
.Fatalf("%stag:%s connsess:%s main_parse_cert error:%v",
113 exampid
, tag
, sngecomm
.Lcs
,
114 e
.Error()) // Handle this ......
116 tc
.RootCAs
= x509
.NewCertPool() // Create a cert "pool"
117 tc
.RootCAs
.AddCert(c
) // Add the CA cert to the pool
118 // Finish TLS Config initialization, so broker can authenticate client.
119 cc
, e
:= tls
.LoadX509KeyPair(cliCertFile
, cliKeyFile
)
121 ll
.Fatalf("%s %s\n", exampid
, e
.Error()) // Handle this ......
123 tc
.Certificates
= append(tc
.Certificates
, cc
) // Add cert
124 // This is OK, but does not seem to be required
125 tc
.BuildNameToCertificate() // Build names map
127 // Standard example TLS connect sequence
128 n
, conn
, e
:= sngecomm
.CommonTLSConnect(exampid
, tag
, ll
, tc
)
130 ll
.Fatalf("%stag:%s connsess:%s main_on_connect error:%v",
131 exampid
, tag
, sngecomm
.Lcs
,
132 e
.Error()) // Handle this ......
136 sngecomm
.DumpTLSConfig(exampid
, tc
, nc
)
138 // *NOTE* application specific functionaltiy starts here!
140 // *NOTE* application specific functionaltiy ends here!
142 // Standard example disconnect sequence
143 e
= sngecomm
.CommonDisconnect(n
, conn
, exampid
, tag
, ll
)
145 ll
.Fatalf("%s %s\n", exampid
, e
.Error()) // Handle this ......
148 ll
.Printf("%stag:%s connsess:%s main_elapsed:%v\n",
149 exampid
, tag
, conn
.Session(),