Skip to content

Commit

Permalink
update SSL validation records for Custom Hostnames and Certificate Packs
Browse files Browse the repository at this point in the history
* CertificatePack was missing `ValidationRecords` and `ValidationErrors`
* Custom Hostnames can now have multiple `ValidationRecord`, this introduces an array (matching CertificatePack), and adds a note about the top-level being deprecated.
  • Loading branch information
nickysemenza committed Feb 2, 2022
1 parent 7adbc2b commit b0ed64f
Show file tree
Hide file tree
Showing 6 changed files with 112 additions and 81 deletions.
2 changes: 2 additions & 0 deletions certificate_packs.go
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,8 @@ type CertificatePack struct {
Hosts []string `json:"hosts"`
Certificates []CertificatePackCertificate `json:"certificates"`
PrimaryCertificate string `json:"primary_certificate"`
ValidationRecords []SSLValidationRecord `json:"validation_records,omitempty"`
ValidationErrors []SSLValidationError `json:"validation_errors,omitempty"`
}

// CertificatePackRequest is used for requesting a new certificate.
Expand Down
40 changes: 19 additions & 21 deletions custom_hostname.go
Original file line number Diff line number Diff line change
Expand Up @@ -43,8 +43,8 @@ type CustomHostnameOwnershipVerification struct {
Value string `json:"value,omitempty"`
}

//CustomHostnameSSLValidationErrors represents errors that occurred during SSL validation.
type CustomHostnameSSLValidationErrors struct {
//SSLValidationError represents errors that occurred during SSL validation.
type SSLValidationError struct {
Message string `json:"message,omitempty"`
}

Expand All @@ -61,25 +61,23 @@ type CustomHostnameSSLCertificates struct {

// CustomHostnameSSL represents the SSL section in a given custom hostname.
type CustomHostnameSSL struct {
ID string `json:"id,omitempty"`
Status string `json:"status,omitempty"`
Method string `json:"method,omitempty"`
Type string `json:"type,omitempty"`
CnameTarget string `json:"cname_target,omitempty"`
CnameName string `json:"cname,omitempty"`
TxtName string `json:"txt_name,omitempty"`
TxtValue string `json:"txt_value,omitempty"`
Wildcard *bool `json:"wildcard,omitempty"`
CustomCertificate string `json:"custom_certificate,omitempty"`
CustomKey string `json:"custom_key,omitempty"`
CertificateAuthority string `json:"certificate_authority,omitempty"`
Issuer string `json:"issuer,omitempty"`
SerialNumber string `json:"serial_number,omitempty"`
Settings CustomHostnameSSLSettings `json:"settings,omitempty"`
ValidationErrors []CustomHostnameSSLValidationErrors `json:"validation_errors,omitempty"`
HTTPUrl string `json:"http_url,omitempty"`
HTTPBody string `json:"http_body,omitempty"`
Certificates []CustomHostnameSSLCertificates `json:"certificates,omitempty"`
ID string `json:"id,omitempty"`
Status string `json:"status,omitempty"`
Method string `json:"method,omitempty"`
Type string `json:"type,omitempty"`
Wildcard *bool `json:"wildcard,omitempty"`
CustomCertificate string `json:"custom_certificate,omitempty"`
CustomKey string `json:"custom_key,omitempty"`
CertificateAuthority string `json:"certificate_authority,omitempty"`
Issuer string `json:"issuer,omitempty"`
SerialNumber string `json:"serial_number,omitempty"`
Settings CustomHostnameSSLSettings `json:"settings,omitempty"`
Certificates []CustomHostnameSSLCertificates `json:"certificates,omitempty"`
// Deprecated, use ValidationRecords.
// If there a single validation record, this will equal ValidationRecords[0] for backwards compatibility.
SSLValidationRecord
ValidationRecords []SSLValidationRecord `json:"validation_records,omitempty"`
ValidationErrors []SSLValidationError `json:"validation_errors,omitempty"`
}

// CustomMetadata defines custom metadata for the hostname. This requires logic to be implemented by Cloudflare to act on the data provided.
Expand Down
98 changes: 59 additions & 39 deletions custom_hostname_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,10 @@ func TestCustomHostname_CreateCustomHostname(t *testing.T) {
"type": "dv",
"cname_target": "dcv.digicert.com",
"cname": "810b7d5f01154524b961ba0cd578acc2.app.example.com",
"validation_records": [{
"cname_target": "dcv.digicert.com",
"cname": "810b7d5f01154524b961ba0cd578acc2.app.example.com"
}],
"settings": {
"http2": "on"
}
Expand All @@ -80,17 +84,21 @@ func TestCustomHostname_CreateCustomHostname(t *testing.T) {

createdAt, _ := time.Parse(time.RFC3339, "2020-02-06T18:11:23.531995Z")

validationRec := SSLValidationRecord{
CnameTarget: "dcv.digicert.com",
CnameName: "810b7d5f01154524b961ba0cd578acc2.app.example.com",
}
want := &CustomHostnameResponse{
Result: CustomHostname{
ID: "0d89c70d-ad9f-4843-b99f-6cc0252067e9",
Hostname: "app.example.com",
CustomOriginServer: "example.app.com",
SSL: &CustomHostnameSSL{
Type: "dv",
Method: "cname",
Status: "pending_validation",
CnameTarget: "dcv.digicert.com",
CnameName: "810b7d5f01154524b961ba0cd578acc2.app.example.com",
Type: "dv",
Method: "cname",
Status: "pending_validation",
SSLValidationRecord: validationRec,
ValidationRecords: []SSLValidationRecord{validationRec},
Settings: CustomHostnameSSLSettings{
HTTP2: "on",
},
Expand Down Expand Up @@ -172,11 +180,13 @@ func TestCustomHostname_CreateCustomHostname_MethodTxt(t *testing.T) {
Hostname: "app.example.com",
CustomOriginServer: "example.app.com",
SSL: &CustomHostnameSSL{
Type: "dv",
Method: "txt",
Status: "pending_validation",
TxtName: "app.example.com",
TxtValue: "ca3-f8db94da174g4c409b17fcaa5470deb2",
Type: "dv",
Method: "txt",
Status: "pending_validation",
SSLValidationRecord: SSLValidationRecord{
TxtName: "app.example.com",
TxtValue: "ca3-f8db94da174g4c409b17fcaa5470deb2",
},
Settings: CustomHostnameSSLSettings{
HTTP2: "on",
},
Expand Down Expand Up @@ -242,11 +252,13 @@ func TestCustomHostname_CreateCustomHostname_CustomOrigin(t *testing.T) {
Hostname: "app.example.com",
CustomOriginServer: "example.app.com",
SSL: &CustomHostnameSSL{
Type: "dv",
Method: "cname",
Status: "pending_validation",
CnameTarget: "dcv.digicert.com",
CnameName: "810b7d5f01154524b961ba0cd578acc2.app.example.com",
Type: "dv",
Method: "cname",
Status: "pending_validation",
SSLValidationRecord: SSLValidationRecord{
CnameTarget: "dcv.digicert.com",
CnameName: "810b7d5f01154524b961ba0cd578acc2.app.example.com",
},
Settings: CustomHostnameSSLSettings{
HTTP2: "on",
},
Expand Down Expand Up @@ -450,16 +462,18 @@ func TestCustomHostname_CustomHostnames(t *testing.T) {
ID: "custom_host_1",
Hostname: "custom.host.one",
SSL: &CustomHostnameSSL{
ID: "0d89c70d-ad9f-4843-b99f-6cc0252067e9",
Type: "dv",
Method: "cname",
Status: "pending_validation",
CnameTarget: "dcv.digicert.com",
CnameName: "810b7d5f01154524b961ba0cd578acc2.app.example.com",
ID: "0d89c70d-ad9f-4843-b99f-6cc0252067e9",
Type: "dv",
Method: "cname",
Status: "pending_validation",
SSLValidationRecord: SSLValidationRecord{
CnameTarget: "dcv.digicert.com",
CnameName: "810b7d5f01154524b961ba0cd578acc2.app.example.com",
HTTPUrl: "http://app.example.com/.well-known/pki-validation/ca3-da12a1c25e7b48cf80408c6c1763b8a2.txt",
HTTPBody: "ca3-574923932a82475cb8592200f1a2a23d",
},
Issuer: "DigiCertInc",
SerialNumber: "6743787633689793699141714808227354901",
HTTPUrl: "http://app.example.com/.well-known/pki-validation/ca3-da12a1c25e7b48cf80408c6c1763b8a2.txt",
HTTPBody: "ca3-574923932a82475cb8592200f1a2a23d",
},
CustomMetadata: CustomMetadata{"a_random_field": "random field value"},
Status: PENDING,
Expand Down Expand Up @@ -595,12 +609,14 @@ func TestCustomHostname_CustomHostname_WithSSLError(t *testing.T) {
ID: "bar",
Hostname: "example.com",
SSL: &CustomHostnameSSL{
Type: "dv",
Method: "cname",
Status: "pending_validation",
CnameName: "810b7d5f01154524b961ba0cd578acc2.example.com",
CnameTarget: "dcv.digicert.com",
ValidationErrors: []CustomHostnameSSLValidationErrors{
Type: "dv",
Method: "cname",
Status: "pending_validation",
SSLValidationRecord: SSLValidationRecord{
CnameName: "810b7d5f01154524b961ba0cd578acc2.example.com",
CnameTarget: "dcv.digicert.com",
},
ValidationErrors: []SSLValidationError{
{
Message: "SERVFAIL looking up CAA for example.com",
},
Expand Down Expand Up @@ -661,11 +677,13 @@ func TestCustomHostname_UpdateCustomHostnameSSL(t *testing.T) {
Hostname: "app.example.com",
CustomOriginServer: "example.app.com",
SSL: &CustomHostnameSSL{
Type: "dv",
Method: "cname",
Status: "pending_validation",
CnameTarget: "dcv.digicert.com",
CnameName: "810b7d5f01154524b961ba0cd578acc2.app.example.com",
Type: "dv",
Method: "cname",
Status: "pending_validation",
SSLValidationRecord: SSLValidationRecord{
CnameTarget: "dcv.digicert.com",
CnameName: "810b7d5f01154524b961ba0cd578acc2.app.example.com",
},
Settings: CustomHostnameSSLSettings{
HTTP2: "off",
TLS13: "on",
Expand Down Expand Up @@ -739,11 +757,13 @@ func TestCustomHostname_UpdateCustomHostname(t *testing.T) {
Hostname: "app.example.com",
CustomOriginServer: "example.app.com",
SSL: &CustomHostnameSSL{
Type: "dv",
Method: "cname",
Status: "pending_validation",
CnameTarget: "dcv.digicert.com",
CnameName: "810b7d5f01154524b961ba0cd578acc2.app.example.com",
Type: "dv",
Method: "cname",
Status: "pending_validation",
SSLValidationRecord: SSLValidationRecord{
CnameTarget: "dcv.digicert.com",
CnameName: "810b7d5f01154524b961ba0cd578acc2.app.example.com",
},
Settings: CustomHostnameSSLSettings{
HTTP2: "off",
TLS13: "on",
Expand Down
14 changes: 14 additions & 0 deletions ssl.go
Original file line number Diff line number Diff line change
Expand Up @@ -158,3 +158,17 @@ func (api *API) DeleteSSL(ctx context.Context, zoneID, certificateID string) err
}
return nil
}

// SSLValidationRecord displays Domain Control Validation tokens.
type SSLValidationRecord struct {
CnameTarget string `json:"cname_target,omitempty"`
CnameName string `json:"cname,omitempty"`

TxtName string `json:"txt_name,omitempty"`
TxtValue string `json:"txt_value,omitempty"`

HTTPUrl string `json:"http_url,omitempty"`
HTTPBody string `json:"http_body,omitempty"`

Emails []string `json:"emails,omitempty"`
}
20 changes: 7 additions & 13 deletions universal_ssl.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,19 +21,13 @@ type universalSSLSettingResponse struct {

// UniversalSSLVerificationDetails represents a universal ssl verification's properties.
type UniversalSSLVerificationDetails struct {
CertificateStatus string `json:"certificate_status"`
VerificationType string `json:"verification_type"`
ValidationMethod string `json:"validation_method"`
CertPackUUID string `json:"cert_pack_uuid"`
VerificationStatus bool `json:"verification_status"`
BrandCheck bool `json:"brand_check"`
VerificationInfo UniversalSSLVerificationInfo `json:"verification_info"`
}

// UniversalSSLVerificationInfo represents DCV record.
type UniversalSSLVerificationInfo struct {
RecordName string `json:"record_name"`
RecordTarget string `json:"record_target"`
CertificateStatus string `json:"certificate_status"`
VerificationType string `json:"verification_type"`
ValidationMethod string `json:"validation_method"`
CertPackUUID string `json:"cert_pack_uuid"`
VerificationStatus bool `json:"verification_status"`
BrandCheck bool `json:"brand_check"`
VerificationInfo []SSLValidationRecord `json:"verification_info"`
}

type universalSSLVerificationResponse struct {
Expand Down
19 changes: 11 additions & 8 deletions universal_ssl_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -88,10 +88,13 @@ func TestUniversalSSLVerificationDetails(t *testing.T) {
"certificate_status": "active",
"verification_type": "cname",
"verification_status": true,
"verification_info": {
"record_name": "b3b90cfedd89a3e487d3e383c56c4267.example.com",
"record_target": "6979be7e4cfc9e5c603e31df7efac9cc60fee82d.comodoca.com"
},
"verification_info": [
{
"status": "pending",
"http_url": "http://example.com/.well-known/acme-challenge/Km-ycWoOVh10cLfL4pRPppGt6jU_mGz8xgvNOxudMiA",
"http_body": "Km-ycWoOVh10cLfL4pRPppGt6jU_mGz8xgvNOxudMiA.Jckzm7Z9uOFls_MXPYibNRz6koY5a8qpI_BeHtDtf-g"
}
],
"brand_check": false,
"validation_method": "txt",
"cert_pack_uuid": "a77f8bd7-3b47-46b4-a6f1-75cf98109948"
Expand All @@ -109,10 +112,10 @@ func TestUniversalSSLVerificationDetails(t *testing.T) {
CertPackUUID: "a77f8bd7-3b47-46b4-a6f1-75cf98109948",
VerificationStatus: true,
BrandCheck: false,
VerificationInfo: UniversalSSLVerificationInfo{
RecordName: "b3b90cfedd89a3e487d3e383c56c4267.example.com",
RecordTarget: "6979be7e4cfc9e5c603e31df7efac9cc60fee82d.comodoca.com",
},
VerificationInfo: []SSLValidationRecord{{
HTTPUrl: "http://example.com/.well-known/acme-challenge/Km-ycWoOVh10cLfL4pRPppGt6jU_mGz8xgvNOxudMiA",
HTTPBody: "Km-ycWoOVh10cLfL4pRPppGt6jU_mGz8xgvNOxudMiA.Jckzm7Z9uOFls_MXPYibNRz6koY5a8qpI_BeHtDtf-g",
}},
},
}

Expand Down

0 comments on commit b0ed64f

Please sign in to comment.