Gracefully transition existing meta assets to new format

The new format is dictated primarily by the ACME spec as implemented by
the new acmez/acme package. It makes a lot more sense.
This commit is contained in:
Matthew Holt 2020-07-30 12:13:45 -06:00
parent 9cc43e5a88
commit 27ab38448f
No known key found for this signature in database
GPG Key ID: 2A349DD577D586A5
2 changed files with 94 additions and 0 deletions

View File

@ -54,9 +54,58 @@ func (am *ACMEManager) getAccount(ca, email string) (acme.Account, error) {
return acct, err
}
acct.PrivateKey, err = decodePrivateKey(keyBytes)
// TODO: July 2020 - transition to new ACME lib and account structure;
// for a while, we will need to convert old accounts to new structure
acct, err = am.transitionAccountToACMEzJuly2020Format(ca, acct, regBytes)
if err != nil {
return acct, fmt.Errorf("one-time account transition: %v", err)
}
return acct, err
}
// TODO: this is a temporary transition helper starting July 2020.
// It can go away when we think enough time has passed that most active assets have transitioned.
func (am *ACMEManager) transitionAccountToACMEzJuly2020Format(ca string, acct acme.Account, regBytes []byte) (acme.Account, error) {
if acct.Status != "" && acct.Location != "" {
return acct, nil
}
var oldAcct struct {
Email string `json:"Email"`
Registration struct {
Body struct {
Status string `json:"status"`
TermsOfServiceAgreed bool `json:"termsOfServiceAgreed"`
Orders string `json:"orders"`
ExternalAccountBinding json.RawMessage `json:"externalAccountBinding"`
} `json:"body"`
URI string `json:"uri"`
} `json:"Registration"`
}
err := json.Unmarshal(regBytes, &oldAcct)
if err != nil {
return acct, fmt.Errorf("decoding into old account type: %v", err)
}
acct.Status = oldAcct.Registration.Body.Status
acct.TermsOfServiceAgreed = oldAcct.Registration.Body.TermsOfServiceAgreed
acct.Location = oldAcct.Registration.URI
acct.ExternalAccountBinding = oldAcct.Registration.Body.ExternalAccountBinding
acct.Orders = oldAcct.Registration.Body.Orders
if oldAcct.Email != "" {
acct.Contact = []string{"mailto:" + oldAcct.Email}
}
err = am.saveAccount(ca, acct)
if err != nil {
return acct, fmt.Errorf("saving converted account: %v", err)
}
return acct, nil
}
// newAccount generates a new private key for a new ACME account, but
// it does not register or save the account.
func (*ACMEManager) newAccount(email string) (acme.Account, error) {

View File

@ -177,6 +177,51 @@ func (cfg *Config) loadCertResource(certNamesKey string) (CertificateResource, e
if err != nil {
return CertificateResource{}, fmt.Errorf("decoding certificate metadata: %v", err)
}
// TODO: July 2020 - transition to new ACME lib and cert resource structure;
// for a while, we will need to convert old cert resources to new structure
certRes, err = cfg.transitionCertMetaToACMEzJuly2020Format(certRes, metaBytes)
if err != nil {
return certRes, fmt.Errorf("one-time certificate resource transition: %v", err)
}
return certRes, nil
}
// TODO: this is a temporary transition helper starting July 2020.
// It can go away when we think enough time has passed that most active assets have transitioned.
func (cfg *Config) transitionCertMetaToACMEzJuly2020Format(certRes CertificateResource, metaBytes []byte) (CertificateResource, error) {
data, ok := certRes.IssuerData.(map[string]interface{})
if !ok {
return certRes, nil
}
if certURL, ok := data["url"].(string); ok && certURL != "" {
return certRes, nil
}
var oldCertRes struct {
SANs []string `json:"sans"`
IssuerData struct {
Domain string `json:"domain"`
CertURL string `json:"certUrl"`
CertStableURL string `json:"certStableUrl"`
} `json:"issuer_data"`
}
err := json.Unmarshal(metaBytes, &oldCertRes)
if err != nil {
return certRes, fmt.Errorf("decoding into old certificate resource type: %v", err)
}
data = map[string]interface{}{
"url": oldCertRes.IssuerData.CertURL,
}
certRes.IssuerData = data
err = cfg.saveCertResource(certRes)
if err != nil {
return certRes, fmt.Errorf("saving converted certificate resource: %v", err)
}
return certRes, nil
}