mirror of
https://github.com/SSLMate/certspotter.git
synced 2026-01-31 09:44:21 +01:00
ctclient: add methods for submitting entries
This commit is contained in:
@@ -22,6 +22,8 @@ import (
|
||||
"net/http"
|
||||
"net/url"
|
||||
"time"
|
||||
|
||||
"software.sslmate.com/src/certspotter/cttypes"
|
||||
)
|
||||
|
||||
var UserAgent = ""
|
||||
@@ -108,3 +110,55 @@ func getRoots(ctx context.Context, httpClient *http.Client, logURL *url.URL) ([]
|
||||
}
|
||||
return parsedResponse.Certificates, nil
|
||||
}
|
||||
|
||||
func addChainOrPreChain(ctx context.Context, httpClient *http.Client, logURL *url.URL, isPreChain bool, chain [][]byte) (*cttypes.SignedCertificateTimestamp, error) {
|
||||
var endpoint string
|
||||
if isPreChain {
|
||||
endpoint = "/ct/v1/add-pre-chain"
|
||||
} else {
|
||||
endpoint = "/ct/v1/add-chain"
|
||||
}
|
||||
fullURL := logURL.JoinPath(endpoint).String()
|
||||
|
||||
requestBody, err := json.Marshal(struct {
|
||||
Chain [][]byte `json:"chain"`
|
||||
}{
|
||||
Chain: chain,
|
||||
})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
request, err := http.NewRequestWithContext(ctx, http.MethodPost, fullURL, bytes.NewReader(requestBody))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
request.Header.Set("User-Agent", UserAgent)
|
||||
request.Header.Set("Content-Type", "application/json")
|
||||
|
||||
if httpClient == nil {
|
||||
httpClient = defaultHTTPClient
|
||||
}
|
||||
|
||||
response, err := httpClient.Do(request)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
responseBody, err := io.ReadAll(response.Body)
|
||||
response.Body.Close()
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("Post %q: error reading response: %w", fullURL, err)
|
||||
}
|
||||
|
||||
if response.StatusCode != 200 {
|
||||
return nil, fmt.Errorf("Post %q: %s (%q)", fullURL, response.Status, bytes.TrimSpace(responseBody))
|
||||
}
|
||||
|
||||
sct := new(cttypes.SignedCertificateTimestamp)
|
||||
if err := json.Unmarshal(responseBody, sct); err != nil {
|
||||
return nil, fmt.Errorf("Post %q: error parsing response JSON: %w", fullURL, err)
|
||||
}
|
||||
|
||||
return sct, nil
|
||||
}
|
||||
|
||||
@@ -16,6 +16,12 @@ import (
|
||||
"software.sslmate.com/src/certspotter/merkletree"
|
||||
)
|
||||
|
||||
type WritableLog interface {
|
||||
AddChain(context.Context, [][]byte) (*cttypes.SignedCertificateTimestamp, error)
|
||||
AddPreChain(context.Context, [][]byte) (*cttypes.SignedCertificateTimestamp, error)
|
||||
GetRoots(context.Context) ([][]byte, error)
|
||||
}
|
||||
|
||||
type Log interface {
|
||||
GetSTH(context.Context) (*cttypes.SignedTreeHead, string, error)
|
||||
GetRoots(context.Context) ([][]byte, error)
|
||||
|
||||
@@ -31,6 +31,14 @@ type RFC6962LogEntry struct {
|
||||
Extra_data []byte `json:"extra_data"`
|
||||
}
|
||||
|
||||
func (ctlog *RFC6962Log) AddChain(ctx context.Context, chain [][]byte) (*cttypes.SignedCertificateTimestamp, error) {
|
||||
return addChainOrPreChain(ctx, ctlog.HTTPClient, ctlog.URL, false, chain)
|
||||
}
|
||||
|
||||
func (ctlog *RFC6962Log) AddPreChain(ctx context.Context, chain [][]byte) (*cttypes.SignedCertificateTimestamp, error) {
|
||||
return addChainOrPreChain(ctx, ctlog.HTTPClient, ctlog.URL, true, chain)
|
||||
}
|
||||
|
||||
func (ctlog *RFC6962Log) GetSTH(ctx context.Context) (*cttypes.SignedTreeHead, string, error) {
|
||||
fullURL := ctlog.URL.JoinPath("/ct/v1/get-sth").String()
|
||||
sth := new(cttypes.SignedTreeHead)
|
||||
|
||||
@@ -46,6 +46,14 @@ type StaticLogEntry struct {
|
||||
chain [][32]byte
|
||||
}
|
||||
|
||||
func (ctlog *StaticLog) AddChain(ctx context.Context, chain [][]byte) (*cttypes.SignedCertificateTimestamp, error) {
|
||||
return addChainOrPreChain(ctx, ctlog.HTTPClient, ctlog.SubmissionURL, false, chain)
|
||||
}
|
||||
|
||||
func (ctlog *StaticLog) AddPreChain(ctx context.Context, chain [][]byte) (*cttypes.SignedCertificateTimestamp, error) {
|
||||
return addChainOrPreChain(ctx, ctlog.HTTPClient, ctlog.SubmissionURL, true, chain)
|
||||
}
|
||||
|
||||
func (ctlog *StaticLog) GetSTH(ctx context.Context) (*cttypes.SignedTreeHead, string, error) {
|
||||
fullURL := ctlog.MonitoringURL.JoinPath("/checkpoint").String()
|
||||
responseBody, err := get(ctx, ctlog.HTTPClient, fullURL)
|
||||
|
||||
Reference in New Issue
Block a user