Exemplo n.º 1
0
static const char *get_cert_common_name(PCCERT_CONTEXT cert)
{
    static char buf[1024];
    const char *name = NULL;
    CERT_NAME_INFO *nameInfo;
    DWORD size;
    BOOL ret = CryptDecodeObjectEx(X509_ASN_ENCODING, X509_NAME,
     cert->pCertInfo->Subject.pbData, cert->pCertInfo->Subject.cbData,
     CRYPT_DECODE_NOCOPY_FLAG | CRYPT_DECODE_ALLOC_FLAG, NULL, &nameInfo,
     &size);

    if (ret)
    {
        PCERT_RDN_ATTR commonName = CertFindRDNAttr(szOID_COMMON_NAME,
         nameInfo);

        if (commonName)
        {
            CertRDNValueToStrA(commonName->dwValueType,
             &commonName->Value, buf, sizeof(buf));
            name = buf;
        }
        LocalFree(nameInfo);
    }
    return name;
}
Exemplo n.º 2
0
static void test_findRDNAttr(void)
{
    PCERT_RDN_ATTR ret;
    static CHAR oid[] = "1.2.3";
    BYTE bin[] = { 0x16,0x09,'J','u','a','n',' ','L','a','n','g' };
    CERT_RDN_ATTR attrs[] = {
     { oid, CERT_RDN_IA5_STRING, { sizeof bin, bin } },
    };
    CERT_RDN rdns[] = {
     { sizeof(attrs) / sizeof(attrs[0]), attrs },
    };
    CERT_NAME_INFO nameInfo = { sizeof(rdns) / sizeof(rdns[0]), rdns };

    if (0)
    {
        /* crashes */
        SetLastError(0xdeadbeef);
        CertFindRDNAttr(NULL, NULL);
        /* returns NULL, last error is ERROR_INVALID_PARAMETER
         * crashes on Vista
         */
        SetLastError(0xdeadbeef);
        ret = CertFindRDNAttr(NULL, &nameInfo);
        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 = CertFindRDNAttr("bogus", &nameInfo);
    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 = CertFindRDNAttr("1.2.4", &nameInfo);
    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 = CertFindRDNAttr("1.2.3", &nameInfo);
    ok(ret != NULL, "CertFindRDNAttr failed: %08x\n", GetLastError());
}
/* sqExtractPeerName: Extract the name from the cert of the remote peer. */
static int sqExtractPeerName(sqSSL *ssl) {
	SECURITY_STATUS ret;
	PCCERT_CONTEXT certHandle = NULL;
	PCERT_NAME_INFO certInfo = NULL;
	PCERT_RDN_ATTR certAttr = NULL;
	DWORD dwSize = 0;
	char tmpBuf[1024];

	if(ssl->peerName) {
		free(ssl->peerName);
		ssl->peerName = NULL;
	}
	ret = QueryContextAttributes(&ssl->sslCtxt, SECPKG_ATTR_REMOTE_CERT_CONTEXT, (PVOID)&certHandle);
	/* No credentials were provided; can't extract peer name */
	if(ret == SEC_E_NO_CREDENTIALS) return 1;

	if(ret != SEC_E_OK) {
		if(ssl->loglevel) printf("sqExtractPeerName: QueryContextAttributes failed (code = %x)\n", ret);
		return 0;
	}

	/* Figure out the size of the blob */
	if(!CryptDecodeObject(X509_ASN_ENCODING | PKCS_7_ASN_ENCODING, X509_NAME,
		certHandle->pCertInfo->Subject.pbData,
		certHandle->pCertInfo->Subject.cbData,
		0, NULL, &dwSize)) {
			if(ssl->loglevel) printf("sqExtractPeerName: CryptDecodeObject failed\n");
			return 0;
	}
	
	/* Get the contents */
	certInfo = alloca(dwSize);
	if(!CryptDecodeObject(X509_ASN_ENCODING | PKCS_7_ASN_ENCODING, X509_NAME, 
		certHandle->pCertInfo->Subject.pbData,
		certHandle->pCertInfo->Subject.cbData,
		0, certInfo, &dwSize)) {
			if(ssl->loglevel) printf("sqExtractPeerName: CryptDecodeObject failed\n");
			return 0;
	}

	/* Fetch the CN from the cert */
	certAttr = CertFindRDNAttr(szOID_COMMON_NAME, certInfo);
	if(certAttr == NULL) return 0;

	/* Translate from RDN to string */
	if(CertRDNValueToStr(CERT_RDN_PRINTABLE_STRING, &certAttr->Value, tmpBuf, sizeof(tmpBuf)) == 0) return 0;
	ssl->peerName = _strdup(tmpBuf);
	if(ssl->loglevel) printf("sqExtractPeerName: Peer name is %s\n", ssl->peerName);

	CertFreeCertificateContext(certHandle);

	return 1;
}
Exemplo n.º 4
0
Arquivo: str.c Projeto: wesgarner/wine
static DWORD cert_get_name_from_rdn_attr(DWORD encodingType,
 const CERT_NAME_BLOB *name, LPCSTR oid, LPWSTR pszNameString, DWORD cchNameString)
{
    CERT_NAME_INFO *nameInfo;
    DWORD bytes = 0, ret = 0;

    if (CryptDecodeObjectEx(encodingType, X509_NAME, name->pbData,
     name->cbData, CRYPT_DECODE_ALLOC_FLAG, NULL, &nameInfo, &bytes))
    {
        PCERT_RDN_ATTR nameAttr = CertFindRDNAttr(oid, nameInfo);

        if (nameAttr)
            ret = CertRDNValueToStrW(nameAttr->dwValueType, &nameAttr->Value,
             pszNameString, cchNameString);
        LocalFree(nameInfo);
    }
    return ret;
}
Exemplo n.º 5
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;
}
Exemplo n.º 6
0
Arquivo: str.c Projeto: wesgarner/wine
DWORD WINAPI CertGetNameStringW(PCCERT_CONTEXT pCertContext, DWORD dwType,
 DWORD dwFlags, void *pvTypePara, LPWSTR pszNameString, DWORD cchNameString)
{
    DWORD ret = 0;
    PCERT_NAME_BLOB name;
    LPCSTR altNameOID;

    TRACE("(%p, %d, %08x, %p, %p, %d)\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_EMAIL_TYPE:
    {
        CERT_ALT_NAME_INFO *info;
        PCERT_ALT_NAME_ENTRY entry = cert_find_alt_name_entry(pCertContext,
         altNameOID, CERT_ALT_NAME_RFC822_NAME, &info);

        if (entry)
        {
            if (!pszNameString)
                ret = strlenW(entry->u.pwszRfc822Name) + 1;
            else if (cchNameString)
            {
                ret = min(strlenW(entry->u.pwszRfc822Name), cchNameString - 1);
                memcpy(pszNameString, entry->u.pwszRfc822Name,
                 ret * sizeof(WCHAR));
                pszNameString[ret++] = 0;
            }
        }
        if (info)
            LocalFree(info);
        if (!ret)
            ret = cert_get_name_from_rdn_attr(pCertContext->dwCertEncodingType,
             name, szOID_RSA_emailAddr, pszNameString, cchNameString);
        break;
    }
    case CERT_NAME_RDN_TYPE:
        if (name->cbData)
            ret = CertNameToStrW(pCertContext->dwCertEncodingType, name,
             *(DWORD *)pvTypePara, pszNameString, cchNameString);
        else
        {
            CERT_ALT_NAME_INFO *info;
            PCERT_ALT_NAME_ENTRY entry = cert_find_alt_name_entry(pCertContext,
             altNameOID, CERT_ALT_NAME_DIRECTORY_NAME, &info);

            if (entry)
                ret = CertNameToStrW(pCertContext->dwCertEncodingType,
                 &entry->u.DirectoryName, *(DWORD *)pvTypePara, pszNameString,
                 cchNameString);
            if (info)
                LocalFree(info);
        }
        break;
    case CERT_NAME_ATTR_TYPE:
        ret = cert_get_name_from_rdn_attr(pCertContext->dwCertEncodingType,
         name, pvTypePara, pszNameString, cchNameString);
        if (!ret)
        {
            CERT_ALT_NAME_INFO *altInfo;
            PCERT_ALT_NAME_ENTRY entry = cert_find_alt_name_entry(pCertContext,
             altNameOID, CERT_ALT_NAME_DIRECTORY_NAME, &altInfo);

            if (entry)
                ret = cert_name_to_str_with_indent(X509_ASN_ENCODING, 0,
                 &entry->u.DirectoryName, 0, pszNameString, cchNameString);
            if (altInfo)
                LocalFree(altInfo);
        }
        break;
    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 *nameInfo = NULL;
        DWORD bytes = 0, i;

        if (CryptDecodeObjectEx(pCertContext->dwCertEncodingType, X509_NAME,
         name->pbData, name->cbData, CRYPT_DECODE_ALLOC_FLAG, NULL, &nameInfo,
         &bytes))
        {
            PCERT_RDN_ATTR nameAttr = NULL;

            for (i = 0; !nameAttr && i < sizeof(simpleAttributeOIDs) /
             sizeof(simpleAttributeOIDs[0]); i++)
                nameAttr = CertFindRDNAttr(simpleAttributeOIDs[i], nameInfo);
            if (nameAttr)
                ret = CertRDNValueToStrW(nameAttr->dwValueType,
                 &nameAttr->Value, pszNameString, cchNameString);
            LocalFree(nameInfo);
        }
        if (!ret)
        {
            CERT_ALT_NAME_INFO *altInfo;
            PCERT_ALT_NAME_ENTRY entry = cert_find_alt_name_entry(pCertContext,
             altNameOID, CERT_ALT_NAME_RFC822_NAME, &altInfo);

            if (altInfo)
            {
                if (!entry && altInfo->cAltEntry)
                    entry = &altInfo->rgAltEntry[0];
                if (entry)
                {
                    if (!pszNameString)
                        ret = strlenW(entry->u.pwszRfc822Name) + 1;
                    else if (cchNameString)
                    {
                        ret = min(strlenW(entry->u.pwszRfc822Name),
                         cchNameString - 1);
                        memcpy(pszNameString, entry->u.pwszRfc822Name,
                         ret * sizeof(WCHAR));
                        pszNameString[ret++] = 0;
                    }
                }
                LocalFree(altInfo);
            }
        }
        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;
    }
    case CERT_NAME_DNS_TYPE:
    {
        CERT_ALT_NAME_INFO *info;
        PCERT_ALT_NAME_ENTRY entry = cert_find_alt_name_entry(pCertContext,
         altNameOID, CERT_ALT_NAME_DNS_NAME, &info);

        if (entry)
        {
            if (!pszNameString)
                ret = strlenW(entry->u.pwszDNSName) + 1;
            else if (cchNameString)
            {
                ret = min(strlenW(entry->u.pwszDNSName), cchNameString - 1);
                memcpy(pszNameString, entry->u.pwszDNSName, ret * sizeof(WCHAR));
                pszNameString[ret++] = 0;
            }
        }
        if (info)
            LocalFree(info);
        if (!ret)
            ret = cert_get_name_from_rdn_attr(pCertContext->dwCertEncodingType,
             name, szOID_COMMON_NAME, pszNameString, cchNameString);
        break;
    }
    case CERT_NAME_URL_TYPE:
    {
        CERT_ALT_NAME_INFO *info;
        PCERT_ALT_NAME_ENTRY entry = cert_find_alt_name_entry(pCertContext,
         altNameOID, CERT_ALT_NAME_URL, &info);

        if (entry)
        {
            if (!pszNameString)
                ret = strlenW(entry->u.pwszURL) + 1;
            else if (cchNameString)
            {
                ret = min(strlenW(entry->u.pwszURL), cchNameString - 1);
                memcpy(pszNameString, entry->u.pwszURL, ret * sizeof(WCHAR));
                pszNameString[ret++] = 0;
            }
        }
        if (info)
            LocalFree(info);
        break;
    }
    default:
        FIXME("unimplemented for type %d\n", dwType);
        ret = 0;
    }
    if (!ret)
    {
        if (!pszNameString)
            ret = 1;
        else if (cchNameString)
        {
            pszNameString[0] = 0;
            ret = 1;
        }
    }
    return ret;
}
Exemplo n.º 7
0
    tstring Win32Certificate::getCertAttribute(const char * whichAttr)
    {
        PCCERT_CONTEXT pContext = getWin32Context();

        // How much space do we need.
        DWORD cbNameInfo = 0;

        DWORD dwRet = CryptDecodeObject(
            X509_ASN_ENCODING,
            X509_NAME,
            pContext->pCertInfo->Subject.pbData,
            pContext->pCertInfo->Subject.cbData,
            CRYPT_DECODE_NOCOPY_FLAG,
            NULL,
            &cbNameInfo);

        DWORD dwErr = GetLastError();

        RCF_VERIFY(
            dwRet, 
            RCF::Exception(
                _RcfError_CryptoApiError("CryptDecodeObject()"), 
                dwErr, 
                RCF::RcfSubsystem_Os));

        std::vector<char> vec(cbNameInfo);

        // Retrieve name info.
        dwRet = CryptDecodeObject(X509_ASN_ENCODING,
            X509_NAME,
            pContext->pCertInfo->Subject.pbData,
            pContext->pCertInfo->Subject.cbData,
            CRYPT_DECODE_NOCOPY_FLAG,
            &vec[0],
            &cbNameInfo);

        dwErr = GetLastError();

        RCF_VERIFY(
            dwRet, 
            RCF::Exception(
                _RcfError_CryptoApiError("CryptDecodeObject()"), 
                dwErr, 
                RCF::RcfSubsystem_Os));

        PCERT_NAME_INFO pCertNameInfo = (PCERT_NAME_INFO) &vec[0];

        PCERT_RDN_ATTR pCertAttr = CertFindRDNAttr(whichAttr, pCertNameInfo);
        if (pCertAttr)
        {
            DWORD cbLen = CertRDNValueToStr(pCertAttr->dwValueType, &pCertAttr->Value, NULL, 0);
            std::vector<TCHAR> vecAttr(cbLen);

            CertRDNValueToStr(
                pCertAttr->dwValueType, 
                &pCertAttr->Value, 
                &vecAttr[0],
                static_cast<DWORD>(vecAttr.size()));

            tstring attr(&vecAttr[0]);
            return attr;
        }
        
        return tstring();
    }