Skip to content

Commit 6825ccb

Browse files
authored
Move github.com/elasitc/beats/v7/common/transport/tlscommon (#19)
1 parent 5b4e674 commit 6825ccb

29 files changed

+3493
-0
lines changed

README.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,3 +16,4 @@ Provided packages:
1616
* `github.com/elastic/elastic-agent-libs/mapstr` is the old `github.com/elastic/beats/v7/libbeat/common.MapStr`. It is an extra layer on top of `map[string]interface{}`.
1717
* `github.com/elastic/elastic-agent-libs/safemapstr` contains safe operations for `mapstr.M`.
1818
* `github.com/elastic/elastic-agent-libs/str` the previous `stringset.go` file from `github.com/elastic/beats/v7/libbeat/common`. It provides a string set implementation.
19+
* `github.com/elastic/elastic-agent-libs/transport/tlscommon` TLS configuration and validation, CA pinning, etc.

transport/tlscommon/ca_pinning.go

Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,60 @@
1+
// Licensed to Elasticsearch B.V. under one or more contributor
2+
// license agreements. See the NOTICE file distributed with
3+
// this work for additional information regarding copyright
4+
// ownership. Elasticsearch B.V. licenses this file to you under
5+
// the Apache License, Version 2.0 (the "License"); you may
6+
// not use this file except in compliance with the License.
7+
// You may obtain a copy of the License at
8+
//
9+
// http://www.apache.org/licenses/LICENSE-2.0
10+
//
11+
// Unless required by applicable law or agreed to in writing,
12+
// software distributed under the License is distributed on an
13+
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
14+
// KIND, either express or implied. See the License for the
15+
// specific language governing permissions and limitations
16+
// under the License.
17+
18+
package tlscommon
19+
20+
import (
21+
"crypto/sha256"
22+
"crypto/x509"
23+
"encoding/base64"
24+
"errors"
25+
)
26+
27+
// ErrCAPinMissmatch is returned when no pin is matched in the verified chain.
28+
var ErrCAPinMissmatch = errors.New("provided CA certificate pins doesn't match any of the certificate authorities used to validate the certificate")
29+
30+
// verifyCAPin loops through the verified chains and will try to match the certificates pin.
31+
//
32+
// NOTE: Defining a PIN to check certificates is not a replacement for the normal TLS validations it's
33+
// an additional validation. In fact if you set `InsecureSkipVerify` to true and a PIN, the
34+
// verifiedChains variable will be empty and the added validation will fail.
35+
func verifyCAPin(hashes []string, verifiedChains [][]*x509.Certificate) error {
36+
for _, chain := range verifiedChains {
37+
for _, certificate := range chain {
38+
h := Fingerprint(certificate)
39+
if matches(hashes, h) {
40+
return nil
41+
}
42+
}
43+
}
44+
return ErrCAPinMissmatch
45+
}
46+
47+
// Fingerprint takes a certificate and create a hash of the DER encoded public key.
48+
func Fingerprint(certificate *x509.Certificate) string {
49+
hash := sha256.Sum256(certificate.RawSubjectPublicKeyInfo)
50+
return base64.StdEncoding.EncodeToString(hash[:])
51+
}
52+
53+
func matches(pins []string, candidate string) bool {
54+
for _, pin := range pins {
55+
if pin == candidate {
56+
return true
57+
}
58+
}
59+
return false
60+
}

0 commit comments

Comments
 (0)