Skip to content

Сломался Gost EnvelopedCMS на win, не работал на Linux #56

@Fasjeit

Description

@Fasjeit

Поломался EnvelopedCms, скорее всего после очередного вливания из upstream. Тестов не было....

При вызове
envelopedCms.Encrypt(recip1);

вываливается
ASN1 bad tag value met

Проблема в том, что после одного из вливаний появился код в PkcsPalWindows.Encrypt.cs

 using (SafeCertContextHandle hCertContext = recipient.Certificate.CreateCertContextHandle())
 {
    CERT_CONTEXT* pCertContext = hCertContext.DangerousGetCertContext();
    CERT_INFO* pCertInfo = pCertContext->pCertInfo;

    CMSG_KEY_TRANS_RECIPIENT_ENCODE_INFO* pEncodeInfo = (CMSG_KEY_TRANS_RECIPIENT_ENCODE_INFO*)(hb.Alloc(sizeof(CMSG_KEY_TRANS_RECIPIENT_ENCODE_INFO)));

    pEncodeInfo->cbSize = sizeof(CMSG_KEY_TRANS_RECIPIENT_ENCODE_INFO);

    RSAEncryptionPadding padding = recipient.RSAEncryptionPadding;

    if (padding is null)
    {
        if (recipient.Certificate.GetKeyAlgorithm() == Oids.RsaOaep)
        {
            byte[] parameters = recipient.Certificate.GetKeyAlgorithmParameters();

            if (parameters == null || parameters.Length == 0)
            {
                padding = RSAEncryptionPadding.OaepSHA1;
            }
            else if (!PkcsHelpers.TryGetRsaOaepEncryptionPadding(parameters, out padding, out _))
            {
                throw ErrorCode.CRYPT_E_UNKNOWN_ALGO.ToCryptographicException();
            }
        }
        else
        {
            padding = RSAEncryptionPadding.Pkcs1;
        }
    }

    if (padding == RSAEncryptionPadding.Pkcs1)
    {
        // ГОСТ ПОПАДАЕТ СЮДА!
        // в результате в параметры и OID попадает RSA, а не гост
        pEncodeInfo->KeyEncryptionAlgorithm.pszObjId = hb.AllocAsciiString(Oids.Rsa);
        pEncodeInfo->KeyEncryptionAlgorithm.Parameters.cbData = (uint)s_rsaPkcsParameters.Length;
        pEncodeInfo->KeyEncryptionAlgorithm.Parameters.pbData = hb.AllocBytes(s_rsaPkcsParameters);
    }
    else if (padding == RSAEncryptionPadding.OaepSHA1)
    {
        pEncodeInfo->KeyEncryptionAlgorithm.pszObjId = hb.AllocAsciiString(Oids.RsaOaep);
        pEncodeInfo->KeyEncryptionAlgorithm.Parameters.cbData = (uint)s_rsaOaepSha1Parameters.Length;
        pEncodeInfo->KeyEncryptionAlgorithm.Parameters.pbData = hb.AllocBytes(s_rsaOaepSha1Parameters);
    }
    else if (padding == RSAEncryptionPadding.OaepSHA256)
    {
        pEncodeInfo->KeyEncryptionAlgorithm.pszObjId = hb.AllocAsciiString(Oids.RsaOaep);
        pEncodeInfo->KeyEncryptionAlgorithm.Parameters.cbData = (uint)s_rsaOaepSha256Parameters.Length;
        pEncodeInfo->KeyEncryptionAlgorithm.Parameters.pbData = hb.AllocBytes(s_rsaOaepSha256Parameters);
    }
    else if (padding == RSAEncryptionPadding.OaepSHA384)
    {
        pEncodeInfo->KeyEncryptionAlgorithm.pszObjId = hb.AllocAsciiString(Oids.RsaOaep);
        pEncodeInfo->KeyEncryptionAlgorithm.Parameters.cbData = (uint)s_rsaOaepSha384Parameters.Length;
        pEncodeInfo->KeyEncryptionAlgorithm.Parameters.pbData = hb.AllocBytes(s_rsaOaepSha384Parameters);
    }
    else if (padding == RSAEncryptionPadding.OaepSHA512)
    {
        pEncodeInfo->KeyEncryptionAlgorithm.pszObjId = hb.AllocAsciiString(Oids.RsaOaep);
        pEncodeInfo->KeyEncryptionAlgorithm.Parameters.cbData = (uint)s_rsaOaepSha512Parameters.Length;
        pEncodeInfo->KeyEncryptionAlgorithm.Parameters.pbData = hb.AllocBytes(s_rsaOaepSha512Parameters);
    }
    else
    {
        throw ErrorCode.CRYPT_E_UNKNOWN_ALGO.ToCryptographicException();
    }

    pEncodeInfo->pvKeyEncryptionAuxInfo = IntPtr.Zero;
    pEncodeInfo->hCryptProv = IntPtr.Zero;

    pEncodeInfo->RecipientPublicKey = pCertInfo->SubjectPublicKeyInfo.PublicKey;

    pEncodeInfo->RecipientId = EncodeRecipientId(recipient, hCertContext, pCertContext, pCertInfo, hb);

    return pEncodeInfo;
}

когда раньше было явное копирование

// KeyEncryptionAlgorithm.pszObjId
IntPtr pszObjId = new IntPtr((long) pKeyEncryptionAlgorithm + (long) Marshal.OffsetOf(typeof(CAPI.CRYPT_ALGORITHM_IDENTIFIER), "pszObjId"));
Marshal.WriteIntPtr(pszObjId, encryptParam.rgszObjId[index].DangerousGetHandle());

// KeyEncryptionAlgorithm.Parameters
IntPtr pParameters = new IntPtr((long) pKeyEncryptionAlgorithm + (long) Marshal.OffsetOf(typeof(CAPI.CRYPT_ALGORITHM_IDENTIFIER), "Parameters"));

// KeyEncryptionAlgorithm.Parameters.cbData
IntPtr pcbData = new IntPtr((long) pParameters + (long) Marshal.OffsetOf(typeof(CAPI.CRYPTOAPI_BLOB), "cbData"));
Marshal.WriteInt32(pcbData, (int) certInfo.SubjectPublicKeyInfo.Algorithm.Parameters.cbData);

// KeyEncryptionAlgorithm.Parameters.pbData
IntPtr ppbData = new IntPtr((long) pParameters + (long) Marshal.OffsetOf(typeof(CAPI.CRYPTOAPI_BLOB), "pbData"));
Marshal.WriteIntPtr(ppbData, certInfo.SubjectPublicKeyInfo.Algorithm.Parameters.pbData);

Metadata

Metadata

Assignees

Labels

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions