Что происходило с этой ошибкой Let's Encrypt CAA? [закрыто]

Недавно Let's Encrypt поделилась этой ошибкой, которая произошла в их системах и приводила к проблемам с сертификатами для их клиентов. Они описывают ошибку следующим образом:

Ошибка: когда запрос сертификата содержал N доменных имен, требующих повторной проверки CAA, Боулдер выбирал одно доменное имя и проверял его N раз. На практике это означает, что если подписчик проверил доменное имя в момент X, а записи CAA для этого домена в момент X разрешили выпуск Let's Encrypt, этот подписчик сможет выдать сертификат, содержащий это доменное имя, до X + 30 дней, даже если кто-то позже установил на это доменное имя записи CAA, запрещающие выпуск Let's Encrypt.

Означает ли это, что когда у пользователя было несколько доменных имен, требующих повторной проверки CA, Let's Encrypt проверит только первый домен? Была ли проблема в том, что сертификаты были выпущены на доменах, которые не принадлежали пользователю, получавшему сертификат?

3
задан 20 March 2020 в 21:49
1 ответ

Let's Encrypt выпустил менее безопасные сертификаты на основе ошибки. Это скорее состояние гонки, чем что-либо еще.

Запись CAA - это дополнительная запись DNS, которая ограничивает поставщиков сертификатов, которым разрешено выдавать сертификаты для домена. Таким образом, если подписчик проверяет доменное имя во время X и записи CAA для домена, разрешенного для выпуска Let's Encrypt, в течение времени, когда подписчик проверяет свой домен, у подписчика будет 30 дней с даты проверки, чтобы выдать действительный сертификаты. Таким образом, если кто-то позже добавит записи CAA, запрещающие выдачу сертификатов LE в любое время между временем X + 30 дней, подписчик сможет выдавать сертификаты, игнорируя запись CAA.

Если вы посмотрите на PR ], в которой была ошибка, именно здесь она впервые сработала, когда в продукте prod. был включен флаг функции NewAuthorizationSchema .

Код проблемы - это распространенная ошибка в Go, см. Соответствующий код для boulder-ra:

// authz2ModelMapToPB converts a mapping of domain name to authz2Models into a
// protobuf authorizations map
func authz2ModelMapToPB(m map[string]authz2Model) (*sapb.Authorizations, error) {
    resp := &sapb.Authorizations{}
    for k, v := range m {
        // Make a copy of k because it will be reassigned with each loop.
        kCopy := k
        authzPB, err := modelToAuthzPB(&v)
        if err != nil {
            return nil, err
        }
        resp.Authz = append(resp.Authz, &sapb.Authorizations_MapElement{Domain: &kCopy, Authz: authzPB})
    }
    return resp, nil
}

В чем проблема: взятие ссылки на переменную итератора цикла Им не удалось правильно обработать переменную итератора второго цикла v .

И, в свою очередь, не удалось учесть два важных поля в этой функции: IdentifierValue и RegistrationID

func modelToAuthzPB(am *authzModel) (*corepb.Authorization, error) {
    expires := am.Expires.UTC().UnixNano()
    id := fmt.Sprintf("%d", am.ID)
    status := uintToStatus[am.Status]
    pb := &corepb.Authorization{
        Id: &id,
        Status: &status,
        Identifier: &am.IdentifierValue,
        RegistrationID: &am.RegistrationID,
        Expires: &expires,
    }

Boulder (в частности, boulder-ra) определяет, что данное FQDN требует повторной проверки CAA и он использует поле идентификатора из объекта авторизации, которое было неверным из-за вышеуказанного коммита. Таким образом, способ обработки поля идентификатора будет одинаковым для всех значений на одной карте. Так, например, если у вас было несколько авторизаций, требующих повторной проверки CAA, boulder-ra перепроверил бы только одно полное доменное имя, а не остальные.

Действительно плохая ошибка.

4
ответ дан 29 March 2020 в 23:43