Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
29 changes: 29 additions & 0 deletions internal/httpx/httpx.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,12 +6,14 @@ import (
"crypto/ecdsa"
"crypto/elliptic"
"crypto/rand"
"crypto/sha256"
"crypto/tls"
"crypto/x509"
"crypto/x509/pkix"
"encoding/base64"
"encoding/pem"
"errors"
"fmt"
"log"
"math/big"
"net/http"
Expand Down Expand Up @@ -113,6 +115,33 @@ func WaitForSvc(
}
}

// GetCertHash returns the SHA-256 fingerprint of the given certificate.
// Notably, the fingerprint is the same as the one displayed by browsers when
// clicking on the "Details" button of a site's certificate.
func GetCertHash(rawCert []byte) (hash [sha256.Size]byte, err error) {
defer errs.Wrap(&err, "failed to get fingerprint")

// Decode the PEM certificate. We expect a single PEM block of type
// "CERTIFICATE".
block, rest := pem.Decode(rawCert)
if block == nil {
return hash, errors.New("no PEM data found")
}
if len(rest) > 0 {
return hash, errors.New("unexpected extra PEM data")
}
if block.Type != "CERTIFICATE" {
return hash, fmt.Errorf("expected type CERTIFICATE but got %s", block.Type)
}

// Parse the certificate and hash its raw bytes.
cert, err := x509.ParseCertificate(block.Bytes)
if err != nil {
return hash, err
}
return sha256.Sum256(cert.Raw), nil
}

// CreateCertificate creates a self-signed certificate and returns the
// PEM-encoded certificate and key. Some of the code below was taken from:
// https://eli.thegreenplace.net/2021/go-https-servers-with-tls/
Expand Down
10 changes: 7 additions & 3 deletions internal/service/service.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@ package service

import (
"context"
"crypto/sha256"
"crypto/tls"
"errors"
"fmt"
Expand Down Expand Up @@ -39,15 +38,20 @@ func Run(
log.Fatalf("Failed to set up system: %v", err)
}

// Create a TLS certificate for the external Web server.
// Create a TLS certificate for the external Web server and determine its
// certificate hash.
cert, key, err := httpx.CreateCertificate(cfg.FQDN)
if err != nil {
log.Fatalf("Failed to create certificate: %v", err)
}
hash, err := httpx.GetCertHash(cert)
if err != nil {
log.Fatalf("Failed to get certificate hash: %v", err)
}

// Initialize hashes for the attestation document.
hashes := new(attestation.Hashes)
hashes.SetTLSHash(addr.Of(sha256.Sum256(cert)))
hashes.SetTLSHash(addr.Of(hash))

// Initialize Web servers.
intSrv := newIntSrv(cfg, hashes, appReady)
Expand Down