From: Dmitry Timoshkov dmitry@baikal.ru
Signed-off-by: Dmitry Timoshkov dmitry@baikal.ru --- dlls/crypt32/msg.c | 44 ++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 44 insertions(+)
diff --git a/dlls/crypt32/msg.c b/dlls/crypt32/msg.c index 5e6d59a1f58..340d7bc3715 100644 --- a/dlls/crypt32/msg.c +++ b/dlls/crypt32/msg.c @@ -746,6 +746,33 @@ static BOOL CRYPT_ConstructBlobArray(DWORD *outCBlobs, return ret; }
+static BOOL CRYPT_AddBlobArray(DWORD *outCBlobs, + PCRYPT_DATA_BLOB *outPBlobs, DWORD cBlobs, const CRYPT_DATA_BLOB *pBlobs) +{ + BOOL ret = TRUE; + + if (cBlobs) + { + CRYPT_DATA_BLOB *new_blobs = CryptMemRealloc(*outPBlobs, (*outCBlobs + cBlobs) * sizeof(CRYPT_DATA_BLOB)); + if (new_blobs) + { + DWORD i; + + *outPBlobs = new_blobs; + + memset(*outPBlobs + *outCBlobs, 0, cBlobs * sizeof(CRYPT_DATA_BLOB)); + for (i = *outCBlobs; ret && i < *outCBlobs + cBlobs; i++) + ret = CRYPT_ConstructBlob(&(*outPBlobs)[i], &pBlobs[i]); + + if (ret) + *outCBlobs += cBlobs; + } + else + ret = FALSE; + } + return ret; +} + static void CRYPT_FreeBlobArray(DWORD cBlobs, PCRYPT_DATA_BLOB blobs) { DWORD i; @@ -3622,6 +3649,23 @@ static BOOL CDecodeMsg_Control(HCRYPTMSG hCryptMsg, DWORD dwFlags, SetLastError(CRYPT_E_INVALID_MSG_TYPE); } break; + case CMSG_CTRL_ADD_CERT: + switch (msg->type) + { + case CMSG_SIGNED: + if (!msg->u.signed_data.info) + { + SetLastError(CRYPT_E_INVALID_MSG_TYPE); + break; + } + ret = CRYPT_AddBlobArray(&msg->u.signed_data.info->cCertEncoded, + &msg->u.signed_data.info->rgCertEncoded, 1, (const CRYPT_DATA_BLOB *)pvCtrlPara); + break; + default: + SetLastError(CRYPT_E_INVALID_MSG_TYPE); + break; + } + break; default: SetLastError(CRYPT_E_CONTROL_TYPE); }
From: Dmitry Timoshkov dmitry@baikal.ru
Signed-off-by: Dmitry Timoshkov dmitry@baikal.ru --- dlls/crypt32/chain.c | 4 ++++ dlls/crypt32/decode.c | 2 ++ dlls/crypt32/encode.c | 2 ++ 3 files changed, 8 insertions(+)
diff --git a/dlls/crypt32/chain.c b/dlls/crypt32/chain.c index fa74ade13d6..ba4dfb3dee3 100644 --- a/dlls/crypt32/chain.c +++ b/dlls/crypt32/chain.c @@ -1662,6 +1662,8 @@ static void dump_extension(const CERT_EXTENSION *ext) dump_name_constraints(ext); else if (!strcmp(ext->pszObjId, szOID_CERT_POLICIES)) dump_cert_policies(ext); + else if (!strcmp(ext->pszObjId, szOID_APPLICATION_CERT_POLICIES)) + FIXME("szOID_APPLICATION_CERT_POLICIES\n"); else if (!strcmp(ext->pszObjId, szOID_ENHANCED_KEY_USAGE)) dump_enhanced_key_usage(ext); else if (!strcmp(ext->pszObjId, szOID_NETSCAPE_CERT_TYPE)) @@ -1820,6 +1822,8 @@ static BOOL CRYPT_CriticalExtensionsSupported(PCCERT_CONTEXT cert) ret = TRUE; else if (!strcmp(oid, szOID_CERT_POLICIES)) ret = TRUE; + else if (!strcmp(oid, szOID_APPLICATION_CERT_POLICIES)) + ret = TRUE; else if (!strcmp(oid, szOID_ENHANCED_KEY_USAGE)) ret = TRUE; else diff --git a/dlls/crypt32/decode.c b/dlls/crypt32/decode.c index 2deacc1cb15..1c6d15f84ed 100644 --- a/dlls/crypt32/decode.c +++ b/dlls/crypt32/decode.c @@ -6940,6 +6940,8 @@ static CryptDecodeObjectExFunc CRYPT_GetBuiltinDecoder(DWORD dwCertEncodingType, decodeFunc = CRYPT_AsnDecodeCRLDistPoints; else if (!strcmp(lpszStructType, szOID_CERT_POLICIES)) decodeFunc = CRYPT_AsnDecodeCertPolicies; + else if (!strcmp(lpszStructType, szOID_APPLICATION_CERT_POLICIES)) + FIXME("szOID_APPLICATION_CERT_POLICIES\n"); else if (!strcmp(lpszStructType, szOID_POLICY_MAPPINGS)) decodeFunc = CRYPT_AsnDecodeCertPolicyMappings; else if (!strcmp(lpszStructType, szOID_POLICY_CONSTRAINTS)) diff --git a/dlls/crypt32/encode.c b/dlls/crypt32/encode.c index 9e362b8db21..ecec1bffa96 100644 --- a/dlls/crypt32/encode.c +++ b/dlls/crypt32/encode.c @@ -4859,6 +4859,8 @@ static CryptEncodeObjectExFunc CRYPT_GetBuiltinEncoder(DWORD dwCertEncodingType, encodeFunc = CRYPT_AsnEncodeCRLDistPoints; else if (!strcmp(lpszStructType, szOID_CERT_POLICIES)) encodeFunc = CRYPT_AsnEncodeCertPolicies; + else if (!strcmp(lpszStructType, szOID_APPLICATION_CERT_POLICIES)) + FIXME("szOID_APPLICATION_CERT_POLICIES\n"); else if (!strcmp(lpszStructType, szOID_POLICY_MAPPINGS)) encodeFunc = CRYPT_AsnEncodeCertPolicyMappings; else if (!strcmp(lpszStructType, szOID_POLICY_CONSTRAINTS))
From: Dmitry Timoshkov dmitry@baikal.ru
Signed-off-by: Dmitry Timoshkov dmitry@baikal.ru --- dlls/crypt32/oid.c | 8 +++++++- include/wincrypt.h | 3 +++ 2 files changed, 10 insertions(+), 1 deletion(-)
diff --git a/dlls/crypt32/oid.c b/dlls/crypt32/oid.c index e00c683e181..9aa4a3e840a 100644 --- a/dlls/crypt32/oid.c +++ b/dlls/crypt32/oid.c @@ -1716,7 +1716,13 @@ PCCRYPT_OID_INFO WINAPI CryptFindOIDInfo(DWORD dwKeyType, void *pvKey, { PCCRYPT_OID_INFO ret = NULL;
- TRACE("(%ld, %p, %ld)\n", dwKeyType, pvKey, dwGroupId); + TRACE("(%#lx, %p, %lu)\n", dwKeyType, pvKey, dwGroupId); + + if (dwKeyType & (CRYPT_OID_INFO_PUBKEY_ENCRYPT_KEY_FLAG | CRYPT_OID_INFO_PUBKEY_SIGN_KEY_FLAG)) + { + FIXME("flags %#lx not supported\n", dwKeyType & (CRYPT_OID_INFO_PUBKEY_ENCRYPT_KEY_FLAG | CRYPT_OID_INFO_PUBKEY_SIGN_KEY_FLAG)); + dwKeyType &= ~(CRYPT_OID_INFO_PUBKEY_ENCRYPT_KEY_FLAG | CRYPT_OID_INFO_PUBKEY_SIGN_KEY_FLAG); + }
switch(dwKeyType) { diff --git a/include/wincrypt.h b/include/wincrypt.h index 5b16760979c..e3a7ad0eb24 100644 --- a/include/wincrypt.h +++ b/include/wincrypt.h @@ -1658,6 +1658,9 @@ typedef const CERT_CRL_CONTEXT_PAIR *PCCERT_CRL_CONTEXT_PAIR; #define CRYPT_OID_INFO_ALGID_KEY 3 #define CRYPT_OID_INFO_SIGN_KEY 4
+#define CRYPT_OID_INFO_PUBKEY_ENCRYPT_KEY_FLAG 0x40000000 +#define CRYPT_OID_INFO_PUBKEY_SIGN_KEY_FLAG 0x80000000 + /* Algorithm IDs */
#define GET_ALG_CLASS(x) (x & (7 << 13))
From: Dmitry Timoshkov dmitry@baikal.ru
Signed-off-by: Dmitry Timoshkov dmitry@baikal.ru --- dlls/crypt32/msg.c | 62 ++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 62 insertions(+)
diff --git a/dlls/crypt32/msg.c b/dlls/crypt32/msg.c index 340d7bc3715..d56e1745404 100644 --- a/dlls/crypt32/msg.c +++ b/dlls/crypt32/msg.c @@ -824,6 +824,25 @@ static BOOL CRYPT_ConstructAttributes(CRYPT_ATTRIBUTES *out, return ret; }
+static BOOL CRYPT_AddAttribute(CRYPT_ATTRIBUTES *out, const CRYPT_ATTRIBUTE *in) +{ + BOOL ret; + CRYPT_ATTRIBUTE *new_attrs; + + new_attrs = CryptMemRealloc(out->rgAttr, (out->cAttr + 1) * sizeof(CRYPT_ATTRIBUTE)); + if (new_attrs) + { + out->rgAttr = new_attrs; + memset(&out->rgAttr[out->cAttr], 0, sizeof(CRYPT_ATTRIBUTE)); + ret = CRYPT_ConstructAttribute(&new_attrs[out->cAttr], in); + if (ret) + out->cAttr++; + } + else + ret = FALSE; + return ret; +} + /* Constructs a CMSG_CMS_SIGNER_INFO from a CMSG_SIGNER_ENCODE_INFO_WITH_CMS. */ static BOOL CSignerInfo_Construct(CMSG_CMS_SIGNER_INFO *info, const CMSG_SIGNER_ENCODE_INFO_WITH_CMS *in) @@ -3666,8 +3685,51 @@ static BOOL CDecodeMsg_Control(HCRYPTMSG hCryptMsg, DWORD dwFlags, break; } break; + case CMSG_CTRL_ADD_SIGNER_UNAUTH_ATTR: + switch (msg->type) + { + case CMSG_SIGNED: + { + CMSG_CTRL_ADD_SIGNER_UNAUTH_ATTR_PARA *param = (CMSG_CTRL_ADD_SIGNER_UNAUTH_ATTR_PARA *)pvCtrlPara; + CRYPT_ATTRIBUTE *attr; + DWORD size; + + if (!msg->u.signed_data.info) + { + SetLastError(CRYPT_E_INVALID_MSG_TYPE); + break; + } + + if (param->dwSignerIndex >= msg->u.signed_data.info->cSignerInfo) + { + SetLastError(CRYPT_E_INVALID_INDEX); + break; + } + + ret = CryptDecodeObjectEx(PKCS_7_ASN_ENCODING, PKCS_ATTRIBUTE, param->blob.pbData, param->blob.cbData, + CRYPT_DECODE_ALLOC_FLAG, NULL, &attr, &size); + if (!ret) + { + WARN("CryptDecodeObjectEx(PKCS_ATTRIBUTE) error %#lx\n", GetLastError()); + break; + } + + TRACE("existing CRYPT_ATTRIBUTES: cAttr = %lu\n", msg->u.signed_data.info->rgSignerInfo[param->dwSignerIndex].UnauthAttrs.cAttr); + TRACE("CRYPT_ATTRIBUTE: %p: pszObjId %s, cValue %lu, rgValue %p\n", attr, debugstr_a(attr->pszObjId), attr->cValue, attr->rgValue); + ret = CRYPT_AddAttribute(&msg->u.signed_data.info->rgSignerInfo[param->dwSignerIndex].UnauthAttrs, attr); + LocalFree(attr); + break; + } + default: + SetLastError(CRYPT_E_INVALID_MSG_TYPE); + break; + } + break; + default: + FIXME("unimplemented for %ld\n", dwCtrlType); SetLastError(CRYPT_E_CONTROL_TYPE); + break; } return ret; }
From: Dmitry Timoshkov dmitry@baikal.ru
Signed-off-by: Dmitry Timoshkov dmitry@baikal.ru --- dlls/crypt32/msg.c | 13 +++++++++++++ 1 file changed, 13 insertions(+)
diff --git a/dlls/crypt32/msg.c b/dlls/crypt32/msg.c index d56e1745404..832d52ddf2b 100644 --- a/dlls/crypt32/msg.c +++ b/dlls/crypt32/msg.c @@ -3264,6 +3264,19 @@ static BOOL CDecodeSignedMsg_GetParam(CDecodeMsg *msg, DWORD dwParamType, else SetLastError(CRYPT_E_INVALID_MSG_TYPE); break; + case CMSG_ENCRYPTED_DIGEST: + if (msg->u.signed_data.info) + { + if (dwIndex >= msg->u.signed_data.info->cSignerInfo) + SetLastError(CRYPT_E_INVALID_INDEX); + else + ret = CRYPT_CopyParam(pvData, pcbData, + &msg->u.signed_data.info->rgSignerInfo[dwIndex].EncryptedHash.pbData, + msg->u.signed_data.info->rgSignerInfo[dwIndex].EncryptedHash.cbData); + } + else + SetLastError(CRYPT_E_INVALID_MSG_TYPE); + break; default: FIXME("unimplemented for %ld\n", dwParamType); SetLastError(CRYPT_E_INVALID_MSG_TYPE);
From: Dmitry Timoshkov dmitry@baikal.ru
Signed-off-by: Dmitry Timoshkov dmitry@baikal.ru --- dlls/crypt32/msg.c | 30 ++++++++++++++++++++++++++++++ 1 file changed, 30 insertions(+)
diff --git a/dlls/crypt32/msg.c b/dlls/crypt32/msg.c index 832d52ddf2b..4d49aebe4b6 100644 --- a/dlls/crypt32/msg.c +++ b/dlls/crypt32/msg.c @@ -3698,6 +3698,36 @@ static BOOL CDecodeMsg_Control(HCRYPTMSG hCryptMsg, DWORD dwFlags, break; } break; + case CMSG_CTRL_DEL_CERT: + switch (msg->type) + { + case CMSG_SIGNED: + { + DWORD index = *(const DWORD *)pvCtrlPara; + + if (!msg->u.signed_data.info) + { + SetLastError(CRYPT_E_INVALID_MSG_TYPE); + break; + } + if (index >= msg->u.signed_data.info->cCertEncoded) + { + SetLastError(CRYPT_E_INVALID_INDEX); + break; + } + TRACE("CMSG_CTRL_DEL_CERT: index %lu of %lu\n", index, msg->u.signed_data.info->cCertEncoded); + CryptMemFree(msg->u.signed_data.info->rgCertEncoded[index].pbData); + memmove(&msg->u.signed_data.info->rgCertEncoded[index], &msg->u.signed_data.info->rgCertEncoded[index + 1], + (msg->u.signed_data.info->cCertEncoded - index - 1) * sizeof(msg->u.signed_data.info->rgCertEncoded)); + msg->u.signed_data.info->cCertEncoded--; + ret = TRUE; + break; + } + default: + SetLastError(CRYPT_E_INVALID_MSG_TYPE); + break; + } + break; case CMSG_CTRL_ADD_SIGNER_UNAUTH_ATTR: switch (msg->type) {
From: Dmitry Timoshkov dmitry@baikal.ru
Signed-off-by: Dmitry Timoshkov dmitry@baikal.ru --- dlls/crypt32/chain.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-)
diff --git a/dlls/crypt32/chain.c b/dlls/crypt32/chain.c index ba4dfb3dee3..f03bc6c1a7b 100644 --- a/dlls/crypt32/chain.c +++ b/dlls/crypt32/chain.c @@ -3864,8 +3864,7 @@ BOOL WINAPI CertVerifyCertificateChainPolicy(LPCSTR szPolicyOID, if (!set) set = CryptInitOIDFunctionSet( CRYPT_OID_VERIFY_CERTIFICATE_CHAIN_POLICY_FUNC, 0); - CryptGetOIDFunctionAddress(set, X509_ASN_ENCODING, szPolicyOID, 0, - (void **)&verifyPolicy, &hFunc); + CryptGetOIDFunctionAddress(set, 0, szPolicyOID, 0, (void **)&verifyPolicy, &hFunc); } if (verifyPolicy) ret = verifyPolicy(szPolicyOID, pChainContext, pPolicyPara,
From: Dmitry Timoshkov dmitry@baikal.ru
At least there are certificates with 2 and 4 bytes of key usage data.
Signed-off-by: Dmitry Timoshkov dmitry@baikal.ru --- dlls/crypt32/chain.c | 7 ------- 1 file changed, 7 deletions(-)
diff --git a/dlls/crypt32/chain.c b/dlls/crypt32/chain.c index f03bc6c1a7b..e7c7afe9147 100644 --- a/dlls/crypt32/chain.c +++ b/dlls/crypt32/chain.c @@ -1737,13 +1737,6 @@ static BOOL CRYPT_KeyUsageValid(CertificateChainEngine *engine, &usage, &size); if (!ret) return FALSE; - else if (usage.cbData > 2) - { - /* The key usage extension only defines 9 bits => no more than 2 - * bytes are needed to encode all known usages. - */ - return FALSE; - } else { /* The only bit relevant to chain validation is the keyCertSign
This merge request was approved by Hans Leidekker.