Skip to content

Commit

Permalink
Merge pull request #263 from pasinskim/1.3.x
Browse files Browse the repository at this point in the history
1.3.x
  • Loading branch information
pasinskim authored Jan 2, 2018
2 parents def00f1 + 2d2623e commit c28cdf6
Show file tree
Hide file tree
Showing 7 changed files with 138 additions and 49 deletions.
19 changes: 0 additions & 19 deletions client/client.crt

This file was deleted.

16 changes: 15 additions & 1 deletion client/client.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ package client
import (
"crypto/tls"
"crypto/x509"
"encoding/pem"
"fmt"
"io/ioutil"
"net"
Expand Down Expand Up @@ -187,11 +188,24 @@ func loadServerTrust(conf Config) (*x509.CertPool, error) {
// Read certificate file.
servcert, err := ioutil.ReadFile(conf.ServerCert)
if err != nil {
log.Errorf("%s is inaccessible: %s", conf.ServerCert, err.Error())
return nil, err
}

if len(servcert) == 0 {
return nil, errors.New("unable to find system and server certificates")
log.Errorf("Both %s and the system certificate pool are empty.",
conf.ServerCert)
return nil, errors.New("server certificate is empty")
}

block, _ := pem.Decode([]byte(servcert))
if block != nil {
cert, err := x509.ParseCertificate(block.Bytes)
if err == nil {
log.Infof("API Gateway certificate (in PEM format): \n%s", string(servcert))
log.Infof("Issuer: %s, Valid from: %s, Valid to: %s",
cert.Issuer.Organization, cert.NotBefore, cert.NotAfter)
}
}

if syscerts == nil {
Expand Down
28 changes: 0 additions & 28 deletions client/client.key

This file was deleted.

40 changes: 39 additions & 1 deletion client/client_auth.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,10 +15,13 @@ package client

import (
"bytes"
"crypto/x509"
"encoding/base64"
"fmt"
"io/ioutil"
"net/http"
"net/url"
"time"

"github.com/mendersoftware/log"
"github.com/pkg/errors"
Expand Down Expand Up @@ -49,7 +52,42 @@ func (u *AuthClient) Request(api ApiRequester, server string, dataSrc AuthDataMe
log.Debugf("making authorization request to server %s with req: %s", server, req)
rsp, err := api.Do(req)
if err != nil {
return nil, errors.Wrapf(err, "failed to execute authorization request")
log.Errorf("Failure occured while executing authorization request: %#v", err)

// checking the detailed reason of the failure
if urlErr, ok := err.(*url.Error); ok {
switch certErr := urlErr.Err.(type) {
case x509.UnknownAuthorityError:
log.Error("Certificate is signed by unknown authority.")
log.Error("If you are using a self-signed certificate, make sure it is " +
"available locally to the Mender client in /etc/mender/server.crt and " +
"is configured properly in /etc/mender/mender.conf.")
log.Error("See https://docs.mender.io/troubleshooting/mender-client#" +
"certificate-signed-by-unknown-authority for more information.")

return nil, errors.Wrapf(err, "certificate signed by unknown authority")

case x509.CertificateInvalidError:
switch certErr.Reason {
case x509.Expired:
log.Error("Certificate has expired or is not yet valid.")
log.Errorf("Current clock is %s", time.Now())
log.Error("Verify that the clock on the device is correct " +
"and/or certificate expiration date is valid.")
log.Error("See https://docs.mender.io/troubleshooting/mender-client#" +
"certificate-expired-or-not-yet-valid for more information.")

return nil, errors.Wrapf(err, "certificate has expired")
default:
log.Errorf("Server certificate is invalid, reason: %#v", certErr.Reason)
}
return nil, errors.Wrapf(err, "certificate exists, but is invalid")
default:
log.Errorf("authorization request error: %v", certErr)
}
}
return nil, errors.Wrapf(err,
"generic error occured while executing authorization request")
}
defer rsp.Body.Close()

Expand Down
59 changes: 59 additions & 0 deletions client/client_auth_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -120,3 +120,62 @@ func TestClientAuth(t *testing.T) {
_, err = client.Request(ac, ts.URL, msger)
assert.Error(t, err)
}

func TestClientAuthExpiredCert(t *testing.T) {
ts := httptest.NewTLSServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
}))
defer ts.Close()

ac, err := NewApiClient(
Config{"server.expired.crt", true, false},
)
assert.NotNil(t, ac)
assert.NoError(t, err)

client := NewAuth()
assert.NotNil(t, client)

msger := &testAuthDataMessenger{
reqData: []byte("foobar"),
}
rsp, err := client.Request(ac, ts.URL, msger)
assert.Error(t, err)
assert.Contains(t, err.Error(), "certificate has expired")
assert.Nil(t, rsp)
}

func TestClientAuthUnknownAuthorityCert(t *testing.T) {
ts := httptest.NewTLSServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
}))
defer ts.Close()

ac, err := NewApiClient(
Config{"server.unknown-authority.crt", true, false},
)
assert.NotNil(t, ac)
assert.NoError(t, err)

client := NewAuth()
assert.NotNil(t, client)

msger := &testAuthDataMessenger{
reqData: []byte("foobar"),
}
rsp, err := client.Request(ac, ts.URL, msger)
assert.Error(t, err)
assert.Contains(t, err.Error(), "certificate signed by unknown authority")
assert.Nil(t, rsp)
}

func TestClientAuthNoCert(t *testing.T) {
ts := httptest.NewTLSServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
}))
defer ts.Close()

ac, err := NewApiClient(
Config{"server.non-existing.crt", true, false},
)
assert.Nil(t, ac)
assert.Error(t, err)
assert.Contains(t, err.Error(), "cannot initialize server trust")
}
11 changes: 11 additions & 0 deletions client/server.expired.crt
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
-----BEGIN CERTIFICATE-----
MIIBmzCCAQQCCQDMKfSEuawBWTANBgkqhkiG9w0BAQsFADASMRAwDgYDVQQKEwdB
Y21lIENvMB4XDTcxMDEwMTEzMDMxNloXDTcyMDEwMTEzMDMxNlowEjEQMA4GA1UE
ChMHQWNtZSBDbzCBnzANBgkqhkiG9w0BAQEFAAOBjQAwgYkCgYEA7i50ACN5g4Hs
t1Qc1pwdi9/SVFOLcY3lROpsrg6pDP7hpX42/Uo2NWyMOIgObAQWcx4t89IdWFfE
D7sRG4uJ1vdSCZtoLL72YSKwh0t5emn2m+KWQZdvl7A7paygcSirQ9axsZRuC453
HWmxZ/YLy2Wndm0srKs/6kwFErU76iUCAwEAATANBgkqhkiG9w0BAQsFAAOBgQAi
K3rBgk+rMIfXtfWO7naaob/b4ASfUbMAwc1J+wOqXOj9O9wf/5xD5O8/pEenmp5k
M3nPb2xzRhRbusFFG0fZebk2U7DUf+JjN8pdiqfW3gDfOQHh3IdeGrLRsZ3A/K7z
j6GZ2oBCoVjobmbA713gcMJggzzBJbCPmGpFjKYHOQ==
-----END CERTIFICATE-----
14 changes: 14 additions & 0 deletions client/server.unknown-authority.crt
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
-----BEGIN CERTIFICATE-----
MIICEjCCAXugAwIBAgIRAMQ8I/xATeFlYDeiX3H1XBkwDQYJKoZIhvcNAQELBQAw
EjEQMA4GA1UEChMHQWNtZSBDbzAeFw03MDAxMDEwMDAwMDBaFw03MDAxMDMwMDAw
MDBaMBIxEDAOBgNVBAoTB0FjbWUgQ28wgZ8wDQYJKoZIhvcNAQEBBQADgY0AMIGJ
AoGBAJiCLkrvs3bels/qVWe5SojBygTrU7D1Qn/dZ7ZSJF1svUuvwDq8p6wHC1y5
tX+KBjOjxtUjUdIQgfuCjAbw2j7hgrpEenieQpVTccb44aRa1ufobjKYhWiIZ+K6
96udAaoSd1tt+TJpU2Ym2gWzWBMSpGAqKdgrmFfFMl/9mHKlAgMBAAGjaDBmMA4G
A1UdDwEB/wQEAwICpDATBgNVHSUEDDAKBggrBgEFBQcDATAPBgNVHRMBAf8EBTAD
AQH/MC4GA1UdEQQnMCWCC2V4YW1wbGUuY29thwR/AAABhxAAAAAAAAAAAAAAAAAA
AAABMA0GCSqGSIb3DQEBCwUAA4GBAH0gC0D1t1fZ+Nv5OWfve1n435EQ/eLOu0NA
AZ3LjRZjByytlBEvdO8F+xVeLhm/924B2G0VItotsg4888R7AZ43TceBFN4LvPDt
iRMfWmk3Z87fOiMADOFlxdCvA5ceA2o1VDnOblcIf8czSaVTXq9vrmCNhE8P0WU0
L/r4D5nk
-----END CERTIFICATE-----

0 comments on commit c28cdf6

Please sign in to comment.