Unmarshal с x509.ParseCertificateRequest терпит неудачу, но openssl в порядке?

Когда я пытаюсь загрузить CSR в кодировке PEM, Golang неправильно анализирует данные ASN.1 внутри CSR. Выдает, что последовательность усечена.

С другой стороны, OpenSSL отлично справляется с CSR и распечатывает правильный CN.

Вот код генерации (в С#):

public string generateCSR(string cn) 
{
    try
    {
        AsymmetricCipherKeyPair pair = this.keyHolder.keypair;

        var subject = new X509Name("CN=" + cn);
        var pkcs10CertificationRequest = new Pkcs10CertificationRequest
            (PkcsObjectIdentifiers.Sha256WithRsaEncryption.Id, subject, pair.Public, null, pair.Private);

        string csr = Convert.ToBase64String(pkcs10CertificationRequest.GetDerEncoded());
        Debug.Log(csr);
        return csr;
    } catch(Exception e) 
    {
        Debug.LogError(e);
    }

    return null;
}

Это отправляется напрямую через HTTP в службу Golang (без какой-либо кодировки URL и т. д.).

Сторона сервера Golang:

// Try to parse CSR
bytes := make([]byte, base64.StdEncoding.DecodedLen(len(csrData)))
n, err := base64.StdEncoding.Decode(bytes, csrData)
if err != nil {
    fmt.Printf("Error whilst parsing PEM: %v\n", err)
    resp.WriteHeader(http.StatusBadRequest)
    return
}

_, err = x509.ParseCertificateRequest(bytes[:n])
if err != nil {
    fmt.Printf("Error whilst parsing ASN.1/REQ CSR: %v\n", err)
    resp.WriteHeader(http.StatusBadRequest)
    return
}

Тест CSR (в PEM):

MIIEWTCCAkECAQAwFjEUMBIGA1UEAwwLdGVzdEFjY291bnQwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQCHu2/2GXBGlEuIWAjhBHXRnT17Pod9aPbTnLwfVSD+1xjchsu2rB83LtSWlfRXoIs4geUTvr2io0iP/kU+IzVZwL/CMzPWoWwq4VH5nQ5QMqCCMEF2g90BmIlLgaopNuQPfAEO64d+3dSFnha3QLbmv2xXe3WwYJ+RTvf+Kij0jgeB3MGzEmlVDiVWlaH4TO5LzY5/CbQgtfDHmhp4LDGe+9vbSkX/m4TXMEg4//21oe7YKO4spM1z9pIUsk8vBb0jDwRFnYRhRjHY5JTzOOM6lewjciOIlOKiBBPb4xSGJeRexZZvl111L/chhLQR701XvSyEn8MQRC6U3/BAhdvvwROPfJoEkbpf5vPYGfmsRr4iwci7XBFlw7q1iJZ6Jk4T4iYaPXl2HF0x9kpbA6eDDKkdJvM0Z6X61Eir6hI8xsyAoTEh4pBRyypl+tTLl1vK1BNEZhaPatTj5N0glCxa/MxODDDri6aobU5mjbYfp1FMdpSYiJub0l7tZvgSCv82ANxjPvT4HLge658C7VOfAQj+kdeGzNgJRSA8/FwJGsbl0RyB0Yn82HrYKB+YQy/e79+i/BIm9yAmBsEjTgrjkNF1izl5PrwQBc/lU9gVbONNvryODV4pG7NrNERSsiwN5YXFWDElDZjO3TaFwbz67raRgX7aBIHlCeINzBVuzwIDAQABMA0GCSqGSIb3DQEBCwUAA4ICAQBFZmrjbbqxerp5oLbmW91fBzinXKLmP8E1bsIyh4GSsWxnN13a9Srbq/VEaNJm+vucAFrptleMCz8GAO5Gm8XobhnMzr6uotn8b2rEDZvo9UHuyqu2H8wI2Te5sqjBjnbH/KOTN83uYLQVODkVve/9VW7e0xxjG8i/OCmyVjVY0sc4U06LRJw4LVqeeOFWJcv0yjxEucwLNodlzm0S3t9Cx0Vkd3cVzq/lwcBTEDHzcfgleOUcOCgbOZF6NDvyuB5VLsS+HwJeIm8tiBF9yqT+RYFKYQjvDy1XT9a1sNqn7jmiV3zwb4vcy16vgAakjyBeWnK87UJQI4XiCyGP61Xchlo5p5yyIu09iJeAN5pHuKCQAYmvEjTF630O5i/e0UHWhIZA0PnG1xAksVv9FpoQh8LjfnG7+XkAYWFxAbiIG/x8rQsyZie9SSvW2hbRykGpNdQYy4wiwt/dx/UaZI3/n24/dE50NWckP8fLeGWqqej0mYWCLjzxult0xELRiVvjNfuHwcfTPBrqmQqG16PII7tjhv0bhszRrIAkcVMpTM0RV/jcSVc4aMLpDRVLElDtaG2qCaJWq5a8MBk1BiYLjI8i8f0cMBXJ2dq9sjzEwl0vGObBui5my9jHgwzY7aPqIO0mgZm5sEpisBZMgCJ9AmK36u7wjqZZC6jnuxYoWg==

Есть ли какая-либо опция, которую я пропустил в парсере ASN в ходу? Почему OpenSSL подходит к этому вводу?


person geNAZt    schedule 05.05.2019    source источник
comment
Просто для уточнения: кодирование PEM основано на кодировании base64, но отличается от него. Здесь не используется кодирование PEM; это просто base64. См. примеры encoding/pem. Однако этот код кажется мне правильным.   -  person Peter    schedule 06.05.2019
comment
Да, это должно работать, кажется, что он правильно анализирует все данные, но ожидает больше данных, чем длина сертификата, и я не могу понять, что там ожидает golang.   -  person geNAZt    schedule 06.05.2019


Ответы (1)


Я нашел ответ на эту проблему.

Bouncycastle не добавляет 0:00 к атрибутам, если экземпляр атрибута не указан (нулевой). Это приводит к неполным закодированным данным.

«Если вы просто видите: Атрибуты: тогда НАБОР отсутствует, и кодировка технически недействительна (но это допустимо)». - https://www.openssl.org/docs/man1.0.2/man1/openssl-req.html

Решение состоит в том, чтобы предоставить CSR пустой DerSet, что приводит к генерации 0:00, указывающей на отсутствие атрибутов.

person geNAZt    schedule 06.05.2019
comment
Проблема здесь в том, что некоторые центры сертификации отклонят запрос PKCS#10, если набор атрибутов пуст (да, я знаю...). Так что BC поддерживает оба. Он не может обеспечить наличие набора, так как это может привести к поломке. Однако решение для этого обстоятельства является правильным. - person David Hook; 06.10.2019