Esempio n. 1
0
File: crl.c Progetto: AlexSteel/wine
BOOL WINAPI CertIsValidCRLForCertificate(PCCERT_CONTEXT pCert,
 PCCRL_CONTEXT pCrl, DWORD dwFlags, void *pvReserved)
{
    PCERT_EXTENSION ext;
    BOOL ret;

    TRACE("(%p, %p, %08x, %p)\n", pCert, pCrl, dwFlags, pvReserved);

    if (!pCert)
        return TRUE;

    if ((ext = CertFindExtension(szOID_ISSUING_DIST_POINT,
     pCrl->pCrlInfo->cExtension, pCrl->pCrlInfo->rgExtension)))
    {
        CRL_ISSUING_DIST_POINT *idp;
        DWORD size;

        if ((ret = CryptDecodeObjectEx(pCrl->dwCertEncodingType,
         X509_ISSUING_DIST_POINT, ext->Value.pbData, ext->Value.cbData,
         CRYPT_DECODE_ALLOC_FLAG, NULL, &idp, &size)))
        {
            if ((ext = CertFindExtension(szOID_CRL_DIST_POINTS,
             pCert->pCertInfo->cExtension, pCert->pCertInfo->rgExtension)))
            {
                CRL_DIST_POINTS_INFO *distPoints;

                if ((ret = CryptDecodeObjectEx(pCert->dwCertEncodingType,
                 X509_CRL_DIST_POINTS, ext->Value.pbData, ext->Value.cbData,
                 CRYPT_DECODE_ALLOC_FLAG, NULL, &distPoints, &size)))
                {
                    DWORD i;

                    ret = FALSE;
                    for (i = 0; !ret && i < distPoints->cDistPoint; i++)
                        ret = match_dist_point_with_issuing_dist_point(
                         &distPoints->rgDistPoint[i], idp);
                    if (!ret)
                        SetLastError(CRYPT_E_NO_MATCH);
                    LocalFree(distPoints);
                }
            }
            else
            {
                /* no CRL dist points extension in cert, can't match the CRL
                 * (which has an issuing dist point extension)
                 */
                ret = FALSE;
                SetLastError(CRYPT_E_NO_MATCH);
            }
            LocalFree(idp);
        }
    }
    else
        ret = TRUE;
    return ret;
}
Esempio n. 2
0
File: str.c Progetto: wesgarner/wine
/* Searches cert's extensions for the alternate name extension with OID
 * altNameOID, and if found, searches it for the alternate name type entryType.
 * If found, returns a pointer to the entry, otherwise returns NULL.
 * Regardless of whether an entry of the desired type is found, if the
 * alternate name extension is present, sets *info to the decoded alternate
 * name extension, which you must free using LocalFree.
 * The return value is a pointer within *info, so don't free *info before
 * you're done with the return value.
 */
static PCERT_ALT_NAME_ENTRY cert_find_alt_name_entry(PCCERT_CONTEXT cert,
 LPCSTR altNameOID, DWORD entryType, PCERT_ALT_NAME_INFO *info)
{
    PCERT_ALT_NAME_ENTRY entry = NULL;
    PCERT_EXTENSION ext = CertFindExtension(altNameOID,
     cert->pCertInfo->cExtension, cert->pCertInfo->rgExtension);

    if (ext)
    {
        DWORD bytes = 0;

        if (CryptDecodeObjectEx(cert->dwCertEncodingType, X509_ALTERNATE_NAME,
         ext->Value.pbData, ext->Value.cbData, CRYPT_DECODE_ALLOC_FLAG, NULL,
         info, &bytes))
        {
            DWORD i;

            for (i = 0; !entry && i < (*info)->cAltEntry; i++)
                if ((*info)->rgAltEntry[i].dwAltNameChoice == entryType)
                    entry = &(*info)->rgAltEntry[i];
        }
    }
    else
        *info = NULL;
    return entry;
}
Esempio n. 3
0
static void test_findExtension(void)
{
    PCERT_EXTENSION ret;
    static CHAR oid[] = "1.2.3";
    BYTE blobbin[] = {0x02,0x01,0x01};
    CERT_EXTENSION ext = { oid, TRUE, { sizeof blobbin, blobbin } };

    /* returns NULL, last error not set */
    SetLastError(0xdeadbeef);
    ret = CertFindExtension(NULL, 0, NULL);
    ok(ret == NULL, "Expected failure\n");
    ok(GetLastError() == 0xdeadbeef, "Last error was set to %08x\n",
     GetLastError());
    if (0)
    {
        /* crashes */
        SetLastError(0xdeadbeef);
        CertFindExtension(NULL, 1, NULL);
        /* returns NULL, last error is ERROR_INVALID_PARAMETER
         * crashes on Vista
         */
        SetLastError(0xdeadbeef);
        ret = CertFindExtension(NULL, 1, &ext);
        ok(!ret && GetLastError() == ERROR_INVALID_PARAMETER,
         "Expected ERROR_INVALID_PARAMETER, got %d (%08x)\n", GetLastError(),
         GetLastError());
    }
    /* returns NULL, last error not set */
    SetLastError(0xdeadbeef);
    ret = CertFindExtension("bogus", 1, &ext);
    ok(ret == NULL, "Expected failure\n");
    ok(GetLastError() == 0xdeadbeef, "Last error was set to %08x\n",
     GetLastError());
    /* returns NULL, last error not set */
    SetLastError(0xdeadbeef);
    ret = CertFindExtension("1.2.4", 1, &ext);
    ok(ret == NULL, "Expected failure\n");
    ok(GetLastError() == 0xdeadbeef, "Last error was set to %08x\n",
     GetLastError());
    /* succeeds, last error not set */
    SetLastError(0xdeadbeef);
    ret = CertFindExtension("1.2.3", 1, &ext);
    ok(ret != NULL, "CertFindExtension failed: %08x\n", GetLastError());
}
Esempio n. 4
0
DWORD WINAPI CertGetNameStringW(PCCERT_CONTEXT pCertContext, DWORD dwType,
 DWORD dwFlags, void *pvTypePara, LPWSTR pszNameString, DWORD cchNameString)
{
    DWORD ret;
    PCERT_NAME_BLOB name;
    LPCSTR altNameOID;

    TRACE("(%p, %ld, %08lx, %p, %p, %ld)\n", pCertContext, dwType,
     dwFlags, pvTypePara, pszNameString, cchNameString);

    if (dwFlags & CERT_NAME_ISSUER_FLAG)
    {
        name = &pCertContext->pCertInfo->Issuer;
        altNameOID = szOID_ISSUER_ALT_NAME;
    }
    else
    {
        name = &pCertContext->pCertInfo->Subject;
        altNameOID = szOID_SUBJECT_ALT_NAME;
    }

    switch (dwType)
    {
    case CERT_NAME_SIMPLE_DISPLAY_TYPE:
    {
        static const LPCSTR simpleAttributeOIDs[] = { szOID_COMMON_NAME,
         szOID_ORGANIZATIONAL_UNIT_NAME, szOID_ORGANIZATION_NAME,
         szOID_RSA_emailAddr };
        CERT_NAME_INFO *info = NULL;
        PCERT_RDN_ATTR nameAttr = NULL;
        DWORD bytes = 0, i;

        if (CryptDecodeObjectEx(pCertContext->dwCertEncodingType, X509_NAME,
         name->pbData, name->cbData, CRYPT_DECODE_ALLOC_FLAG, NULL, &info,
         &bytes))
        {
            for (i = 0; !nameAttr && i < sizeof(simpleAttributeOIDs) /
             sizeof(simpleAttributeOIDs[0]); i++)
                nameAttr = CertFindRDNAttr(simpleAttributeOIDs[i], info);
        }
        else
            ret = 0;
        if (!nameAttr)
        {
            PCERT_EXTENSION ext = CertFindExtension(altNameOID,
             pCertContext->pCertInfo->cExtension,
             pCertContext->pCertInfo->rgExtension);

            if (ext)
            {
                for (i = 0; !nameAttr && i < sizeof(simpleAttributeOIDs) /
                 sizeof(simpleAttributeOIDs[0]); i++)
                    nameAttr = CertFindRDNAttr(simpleAttributeOIDs[i], info);
                if (!nameAttr)
                {
                    /* FIXME: gotta then look for a rfc822Name choice in ext.
                     * Failing that, look for the first attribute.
                     */
                    FIXME("CERT_NAME_SIMPLE_DISPLAY_TYPE: stub\n");
                    ret = 0;
                }
            }
        }
        ret = CertRDNValueToStrW(nameAttr->dwValueType, &nameAttr->Value,
         pszNameString, cchNameString);
        if (info)
            LocalFree(info);
        break;
    }
    case CERT_NAME_FRIENDLY_DISPLAY_TYPE:
    {
        DWORD cch = cchNameString;

        if (CertGetCertificateContextProperty(pCertContext,
         CERT_FRIENDLY_NAME_PROP_ID, pszNameString, &cch))
            ret = cch;
        else
            ret = CertGetNameStringW(pCertContext,
             CERT_NAME_SIMPLE_DISPLAY_TYPE, dwFlags, pvTypePara, pszNameString,
             cchNameString);
        break;
    }
    default:
        FIXME("unimplemented for type %ld\n", dwType);
        ret = 0;
    }
    return ret;
}
Esempio n. 5
0
File: crl.c Progetto: AlexSteel/wine
static BOOL compare_crl_issued_by(PCCRL_CONTEXT pCrlContext, DWORD dwType,
 DWORD dwFlags, const void *pvPara)
{
    BOOL ret;

    if (pvPara)
    {
        PCCERT_CONTEXT issuer = pvPara;

        ret = CertCompareCertificateName(issuer->dwCertEncodingType,
         &issuer->pCertInfo->Subject, &pCrlContext->pCrlInfo->Issuer);
        if (ret && (dwFlags & CRL_FIND_ISSUED_BY_SIGNATURE_FLAG))
            ret = CryptVerifyCertificateSignatureEx(0,
             issuer->dwCertEncodingType,
             CRYPT_VERIFY_CERT_SIGN_SUBJECT_CRL, (void *)pCrlContext,
             CRYPT_VERIFY_CERT_SIGN_ISSUER_CERT, (void *)issuer, 0, NULL);
        if (ret && (dwFlags & CRL_FIND_ISSUED_BY_AKI_FLAG))
        {
            PCERT_EXTENSION ext = CertFindExtension(
             szOID_AUTHORITY_KEY_IDENTIFIER2, pCrlContext->pCrlInfo->cExtension,
             pCrlContext->pCrlInfo->rgExtension);

            if (ext)
            {
                CERT_AUTHORITY_KEY_ID2_INFO *info;
                DWORD size;

                if ((ret = CryptDecodeObjectEx(X509_ASN_ENCODING,
                 X509_AUTHORITY_KEY_ID2, ext->Value.pbData, ext->Value.cbData,
                 CRYPT_DECODE_ALLOC_FLAG, NULL, &info, &size)))
                {
                    if (info->AuthorityCertIssuer.cAltEntry &&
                     info->AuthorityCertSerialNumber.cbData)
                    {
                        PCERT_ALT_NAME_ENTRY directoryName = NULL;
                        DWORD i;

                        for (i = 0; !directoryName &&
                         i < info->AuthorityCertIssuer.cAltEntry; i++)
                            if (info->AuthorityCertIssuer.rgAltEntry[i].
                             dwAltNameChoice == CERT_ALT_NAME_DIRECTORY_NAME)
                                directoryName =
                                 &info->AuthorityCertIssuer.rgAltEntry[i];
                        if (directoryName)
                        {
                            ret = CertCompareCertificateName(
                             issuer->dwCertEncodingType,
                             &issuer->pCertInfo->Subject,
                             &directoryName->u.DirectoryName);
                            if (ret)
                                ret = CertCompareIntegerBlob(
                                 &issuer->pCertInfo->SerialNumber,
                                 &info->AuthorityCertSerialNumber);
                        }
                        else
                        {
                            FIXME("no supported name type in authority key id2\n");
                            ret = FALSE;
                        }
                    }
                    else if (info->KeyId.cbData)
                    {
                        DWORD size;

                        ret = CertGetCertificateContextProperty(issuer,
                         CERT_KEY_IDENTIFIER_PROP_ID, NULL, &size);
                        if (ret && size == info->KeyId.cbData)
                        {
                            LPBYTE buf = CryptMemAlloc(size);

                            if (buf)
                            {
                                CertGetCertificateContextProperty(issuer,
                                 CERT_KEY_IDENTIFIER_PROP_ID, buf, &size);
                                ret = !memcmp(buf, info->KeyId.pbData, size);
                                CryptMemFree(buf);
                            }
                            else
                                ret = FALSE;
                        }
                        else
                            ret = FALSE;
                    }
                    else
                    {
                        FIXME("unsupported value for AKI extension\n");
                        ret = FALSE;
                    }
                    LocalFree(info);
                }
            }
            /* else: a CRL without an AKI matches any cert */
        }
    }
    else
        ret = TRUE;
    return ret;
}
Esempio n. 6
0
void SchannelCertificate::parse()
{
    //
    // Subject name
    //
    DWORD requiredSize = CertNameToStr(X509_ASN_ENCODING, &m_cert->pCertInfo->Subject, CERT_OID_NAME_STR, NULL, 0);
    if (requiredSize > 1)
    {
        vector<char> rawSubjectName(requiredSize);
        CertNameToStr(X509_ASN_ENCODING, &m_cert->pCertInfo->Subject, CERT_OID_NAME_STR, &rawSubjectName[0], rawSubjectName.size());
        m_subjectName = std::string(&rawSubjectName[0]);
    }

    //
    // Common name
    //
    // Note: We only pull out one common name from the cert.
    requiredSize = CertGetNameString(m_cert, CERT_NAME_ATTR_TYPE, 0, szOID_COMMON_NAME, NULL, 0);
    if (requiredSize > 1)
    {
        vector<char> rawCommonName(requiredSize);
        requiredSize = CertGetNameString(m_cert, CERT_NAME_ATTR_TYPE, 0, szOID_COMMON_NAME, &rawCommonName[0], rawCommonName.size());
        m_commonNames.push_back( std::string(&rawCommonName[0]) );
    }

    //
    // Subject alternative names
    //
    PCERT_EXTENSION pExtensions = CertFindExtension(szOID_SUBJECT_ALT_NAME2, m_cert->pCertInfo->cExtension, m_cert->pCertInfo->rgExtension);
    if (pExtensions)
    {
        CRYPT_DECODE_PARA decodePara = {0};
        decodePara.cbSize = sizeof(decodePara);

        CERT_ALT_NAME_INFO* pAltNameInfo = NULL;
        DWORD altNameInfoSize = 0;

        BOOL status = CryptDecodeObjectEx(
            X509_ASN_ENCODING | PKCS_7_ASN_ENCODING,
            szOID_SUBJECT_ALT_NAME2,
            pExtensions->Value.pbData,
            pExtensions->Value.cbData,
            CRYPT_DECODE_ALLOC_FLAG | CRYPT_DECODE_NOCOPY_FLAG,
            &decodePara,
            &pAltNameInfo,
            &altNameInfoSize);

        if (status && pAltNameInfo)
        {
            for (int i = 0; i < pAltNameInfo->cAltEntry; i++)
            {
                if (pAltNameInfo->rgAltEntry[i].dwAltNameChoice == CERT_ALT_NAME_DNS_NAME)
                    addDNSName( wstrToStr( pAltNameInfo->rgAltEntry[i].pwszDNSName ) );
            }
        }
    }

    //     if (pExtensions)
    //     {
    //         vector<wchar_t> subjectAlt
    //         CryptDecodeObject(X509_ASN_ENCODING | PKCS_7_ASN_ENCODING, szOID_SUBJECT_ALT_NAME, pExtensions->Value->pbData, pExtensions->Value->cbData, )
    //     }
    //
    //     // subjectAltNames
    //     int subjectAltNameLoc = X509_get_ext_by_NID(cert.get(), NID_subject_alt_name, -1);
    //     if(subjectAltNameLoc != -1) {
    //         X509_EXTENSION* extension = X509_get_ext(cert.get(), subjectAltNameLoc);
    //         std::shared_ptr<GENERAL_NAMES> generalNames(reinterpret_cast<GENERAL_NAMES*>(X509V3_EXT_d2i(extension)), GENERAL_NAMES_free);
    //         std::shared_ptr<ASN1_OBJECT> xmppAddrObject(OBJ_txt2obj(ID_ON_XMPPADDR_OID, 1), ASN1_OBJECT_free);
    //         std::shared_ptr<ASN1_OBJECT> dnsSRVObject(OBJ_txt2obj(ID_ON_DNSSRV_OID, 1), ASN1_OBJECT_free);
    //         for (int i = 0; i < sk_GENERAL_NAME_num(generalNames.get()); ++i) {
    //             GENERAL_NAME* generalName = sk_GENERAL_NAME_value(generalNames.get(), i);
    //             if (generalName->type == GEN_OTHERNAME) {
    //                 OTHERNAME* otherName = generalName->d.otherName;
    //                 if (OBJ_cmp(otherName->type_id, xmppAddrObject.get()) == 0) {
    //                     // XmppAddr
    //                     if (otherName->value->type != V_ASN1_UTF8STRING) {
    //                         continue;
    //                     }
    //                     ASN1_UTF8STRING* xmppAddrValue = otherName->value->value.utf8string;
    //                     addXMPPAddress(ByteArray(ASN1_STRING_data(xmppAddrValue), ASN1_STRING_length(xmppAddrValue)).toString());
    //                 }
    //                 else if (OBJ_cmp(otherName->type_id, dnsSRVObject.get()) == 0) {
    //                     // SRVName
    //                     if (otherName->value->type != V_ASN1_IA5STRING) {
    //                         continue;
    //                     }
    //                     ASN1_IA5STRING* srvNameValue = otherName->value->value.ia5string;
    //                     addSRVName(ByteArray(ASN1_STRING_data(srvNameValue), ASN1_STRING_length(srvNameValue)).toString());
    //                 }
    //             }
    //             else if (generalName->type == GEN_DNS) {
    //                 // DNSName
    //                 addDNSName(ByteArray(ASN1_STRING_data(generalName->d.dNSName), ASN1_STRING_length(generalName->d.dNSName)).toString());
    //             }
    //         }
    //     }
}
Esempio n. 7
0
/***********************************************************************
 *		TrustIsCertificateSelfSigned (WINTRUST.@)
 */
BOOL WINAPI TrustIsCertificateSelfSigned( PCCERT_CONTEXT cert )
{
    PCERT_EXTENSION ext;
    DWORD size;
    BOOL ret;

    TRACE("%p\n", cert);
    if ((ext = CertFindExtension(szOID_AUTHORITY_KEY_IDENTIFIER2,
     cert->pCertInfo->cExtension, cert->pCertInfo->rgExtension)))
    {
        CERT_AUTHORITY_KEY_ID2_INFO *info;

        ret = CryptDecodeObjectEx(cert->dwCertEncodingType,
         X509_AUTHORITY_KEY_ID2, ext->Value.pbData, ext->Value.cbData,
         CRYPT_DECODE_ALLOC_FLAG | CRYPT_DECODE_NOCOPY_FLAG, NULL,
         &info, &size);
        if (ret)
        {
            if (info->AuthorityCertIssuer.cAltEntry &&
             info->AuthorityCertSerialNumber.cbData)
            {
                PCERT_ALT_NAME_ENTRY directoryName = NULL;
                DWORD i;

                for (i = 0; !directoryName &&
                 i < info->AuthorityCertIssuer.cAltEntry; i++)
                    if (info->AuthorityCertIssuer.rgAltEntry[i].dwAltNameChoice
                     == CERT_ALT_NAME_DIRECTORY_NAME)
                        directoryName =
                         &info->AuthorityCertIssuer.rgAltEntry[i];
                if (directoryName)
                {
                    ret = CertCompareCertificateName(cert->dwCertEncodingType,
                     &directoryName->u.DirectoryName, &cert->pCertInfo->Issuer)
                     && CertCompareIntegerBlob(&info->AuthorityCertSerialNumber,
                     &cert->pCertInfo->SerialNumber);
                }
                else
                {
                    FIXME("no supported name type in authority key id2\n");
                    ret = FALSE;
                }
            }
            else if (info->KeyId.cbData)
            {
                ret = CertGetCertificateContextProperty(cert,
                 CERT_KEY_IDENTIFIER_PROP_ID, NULL, &size);
                if (ret && size == info->KeyId.cbData)
                {
                    LPBYTE buf = CryptMemAlloc(size);

                    if (buf)
                    {
                        CertGetCertificateContextProperty(cert,
                         CERT_KEY_IDENTIFIER_PROP_ID, buf, &size);
                        ret = !memcmp(buf, info->KeyId.pbData, size);
                        CryptMemFree(buf);
                    }
                    else
                        ret = FALSE;
                }
                else
                    ret = FALSE;
            }
            LocalFree(info);
        }
    }
    else if ((ext = CertFindExtension(szOID_AUTHORITY_KEY_IDENTIFIER,
     cert->pCertInfo->cExtension, cert->pCertInfo->rgExtension)))
    {
        CERT_AUTHORITY_KEY_ID_INFO *info;

        ret = CryptDecodeObjectEx(cert->dwCertEncodingType,
         X509_AUTHORITY_KEY_ID, ext->Value.pbData, ext->Value.cbData,
         CRYPT_DECODE_ALLOC_FLAG | CRYPT_DECODE_NOCOPY_FLAG, NULL,
         &info, &size);
        if (ret)
        {
            if (info->CertIssuer.cbData && info->CertSerialNumber.cbData)
            {
                ret = CertCompareCertificateName(cert->dwCertEncodingType,
                 &info->CertIssuer, &cert->pCertInfo->Issuer) &&
                 CertCompareIntegerBlob(&info->CertSerialNumber,
                 &cert->pCertInfo->SerialNumber);
            }
            else if (info->KeyId.cbData)
            {
                ret = CertGetCertificateContextProperty(cert,
                 CERT_KEY_IDENTIFIER_PROP_ID, NULL, &size);
                if (ret && size == info->KeyId.cbData)
                {
                    LPBYTE buf = CryptMemAlloc(size);

                    if (buf)
                    {
                        CertGetCertificateContextProperty(cert,
                         CERT_KEY_IDENTIFIER_PROP_ID, buf, &size);
                        ret = !memcmp(buf, info->KeyId.pbData, size);
                        CryptMemFree(buf);
                    }
                    else
                        ret = FALSE;
                }
                else
                    ret = FALSE;
            }
            else
                ret = FALSE;
            LocalFree(info);
        }
    }
    else
        ret = CertCompareCertificateName(cert->dwCertEncodingType,
         &cert->pCertInfo->Subject, &cert->pCertInfo->Issuer);
    return ret;
}