Skip to content

Commit 9da4115

Browse files
committed
Factored function to scrape TLS certs from webserver
1 parent 62bbbba commit 9da4115

File tree

3 files changed

+59
-43
lines changed

3 files changed

+59
-43
lines changed

Diff for: certificates/certutils.go

+55
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
/*
2+
arduino-fwuploader
3+
Copyright (c) 2023 Arduino LLC. All right reserved.
4+
5+
This program is free software: you can redistribute it and/or modify
6+
it under the terms of the GNU Affero General Public License as published
7+
by the Free Software Foundation, either version 3 of the License, or
8+
(at your option) any later version.
9+
10+
This program is distributed in the hope that it will be useful,
11+
but WITHOUT ANY WARRANTY; without even the implied warranty of
12+
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13+
GNU Affero General Public License for more details.
14+
15+
You should have received a copy of the GNU Affero General Public License
16+
along with this program. If not, see <https://www.gnu.org/licenses/>.
17+
*/
18+
19+
package certificates
20+
21+
import (
22+
"crypto/tls"
23+
"crypto/x509"
24+
"fmt"
25+
26+
"github.com/sirupsen/logrus"
27+
)
28+
29+
// ScrapeRootCertificatesFromURL downloads from a webserver the root certificate
30+
// required to connect to that server from the TLS handshake response.
31+
func ScrapeRootCertificatesFromURL(URL string) (*x509.Certificate, error) {
32+
conn, err := tls.Dial("tcp", URL, &tls.Config{
33+
InsecureSkipVerify: true,
34+
})
35+
if err != nil {
36+
logrus.Error(err)
37+
return nil, err
38+
}
39+
defer conn.Close()
40+
41+
if err := conn.Handshake(); err != nil {
42+
logrus.Error(err)
43+
return nil, err
44+
}
45+
46+
peerCertificates := conn.ConnectionState().PeerCertificates
47+
if len(peerCertificates) == 0 {
48+
err = fmt.Errorf("no peer certificates found at %s", URL)
49+
logrus.Error(err)
50+
return nil, err
51+
}
52+
53+
rootCertificate := peerCertificates[len(peerCertificates)-1]
54+
return rootCertificate, nil
55+
}

Diff for: flasher/nina.go

+2-22
Original file line numberDiff line numberDiff line change
@@ -21,14 +21,14 @@ package flasher
2121
import (
2222
"bytes"
2323
"crypto/md5"
24-
"crypto/tls"
2524
"crypto/x509"
2625
"encoding/binary"
2726
"encoding/pem"
2827
"fmt"
2928
"io"
3029
"time"
3130

31+
"github.com/arduino/arduino-fwuploader/certificates"
3232
"github.com/arduino/go-paths-helper"
3333
"github.com/sirupsen/logrus"
3434
"go.bug.st/serial"
@@ -165,30 +165,10 @@ func (f *NinaFlasher) certificateFromFile(certificateFile *paths.Path) ([]byte,
165165
}
166166

167167
func (f *NinaFlasher) certificateFromURL(URL string) ([]byte, error) {
168-
config := &tls.Config{
169-
InsecureSkipVerify: true,
170-
}
171-
172-
conn, err := tls.Dial("tcp", URL, config)
168+
rootCertificate, err := certificates.ScrapeRootCertificatesFromURL(URL)
173169
if err != nil {
174-
logrus.Error(err)
175-
return nil, err
176-
}
177-
defer conn.Close()
178-
179-
if err := conn.Handshake(); err != nil {
180-
logrus.Error(err)
181-
return nil, err
182-
}
183-
184-
peerCertificates := conn.ConnectionState().PeerCertificates
185-
if len(peerCertificates) == 0 {
186-
err = fmt.Errorf("no peer certificates found at %s", URL)
187-
logrus.Error(err)
188170
return nil, err
189171
}
190-
191-
rootCertificate := peerCertificates[len(peerCertificates)-1]
192172
return pem.EncodeToMemory(&pem.Block{Type: "CERTIFICATE", Bytes: rootCertificate.Raw}), nil
193173
}
194174

Diff for: flasher/winc.go

+2-21
Original file line numberDiff line numberDiff line change
@@ -21,14 +21,14 @@ package flasher
2121
import (
2222
"bytes"
2323
"crypto/rsa"
24-
"crypto/tls"
2524
"crypto/x509"
2625
"encoding/binary"
2726
"errors"
2827
"fmt"
2928
"io"
3029
"time"
3130

31+
"github.com/arduino/arduino-fwuploader/certificates"
3232
"github.com/arduino/go-paths-helper"
3333
"github.com/sirupsen/logrus"
3434
"go.bug.st/serial"
@@ -133,29 +133,10 @@ func (f *WincFlasher) certificateFromFile(certificateFile *paths.Path) ([]byte,
133133
}
134134

135135
func (f *WincFlasher) certificateFromURL(URL string) ([]byte, error) {
136-
config := &tls.Config{
137-
InsecureSkipVerify: true,
138-
}
139-
140-
conn, err := tls.Dial("tcp", URL, config)
136+
rootCertificate, err := certificates.ScrapeRootCertificatesFromURL(URL)
141137
if err != nil {
142-
logrus.Error(err)
143-
return nil, err
144-
}
145-
defer conn.Close()
146-
147-
if err := conn.Handshake(); err != nil {
148-
logrus.Error(err)
149-
return nil, err
150-
}
151-
152-
peerCertificates := conn.ConnectionState().PeerCertificates
153-
if len(peerCertificates) == 0 {
154-
err = fmt.Errorf("no peer certificates found at %s", URL)
155-
logrus.Error(err)
156138
return nil, err
157139
}
158-
rootCertificate := peerCertificates[len(peerCertificates)-1]
159140
return f.getCertificateData(rootCertificate)
160141
}
161142

0 commit comments

Comments
 (0)