static void setup_x509_schannel_create_ecc_mocks(void)
{
    STRICT_EXPECTED_CALL(gballoc_malloc(IGNORED_NUM_ARG)); /*this is creating the handle storage space*/
    STRICT_EXPECTED_CALL(CryptStringToBinaryA("certificate", 0, CRYPT_STRING_ANY, NULL, IGNORED_PTR_ARG, NULL, NULL)); /*this is asking for "how big is the certificate binary size?"*/
    STRICT_EXPECTED_CALL(gballoc_malloc(IGNORED_NUM_ARG)); /*this is creating the binary storage for the certificate*/
    STRICT_EXPECTED_CALL(CryptStringToBinaryA("certificate", 0, CRYPT_STRING_ANY, IGNORED_PTR_ARG, IGNORED_PTR_ARG, NULL, NULL)); /*this is asking for "fill in the certificate in this binary buffer"*/
    STRICT_EXPECTED_CALL(CryptStringToBinaryA("private key", 0, CRYPT_STRING_ANY, NULL, IGNORED_PTR_ARG, NULL, NULL)); /*this is asking for "how big is the private key binary size?"*/
    STRICT_EXPECTED_CALL(gballoc_malloc(IGNORED_NUM_ARG)); /*this is creating the binary storage for the private key*/
    STRICT_EXPECTED_CALL(CryptStringToBinaryA("private key", 0, CRYPT_STRING_ANY, IGNORED_PTR_ARG, IGNORED_PTR_ARG, NULL, NULL)); /*this is asking for "fill in the private key in this binary buffer"*/
    STRICT_EXPECTED_CALL(CryptDecodeObjectEx(X509_ASN_ENCODING | PKCS_7_ASN_ENCODING, PKCS_RSA_PRIVATE_KEY, IGNORED_PTR_ARG, IGNORED_NUM_ARG, 0, NULL, NULL, IGNORED_PTR_ARG)).SetReturn(FALSE); /*this is asking "how big is the decoded private key? (from binary)*/
    STRICT_EXPECTED_CALL(CryptDecodeObjectEx(X509_ASN_ENCODING | PKCS_7_ASN_ENCODING, X509_ECC_PRIVATE_KEY, IGNORED_PTR_ARG, IGNORED_NUM_ARG, 0, NULL, NULL, IGNORED_PTR_ARG)); /*this is asking "how big is the decoded private key? (from binary)*/
    STRICT_EXPECTED_CALL(gballoc_malloc(IGNORED_NUM_ARG)); /*this is allocating space for the decoded private key*/
    STRICT_EXPECTED_CALL(CryptDecodeObjectEx(X509_ASN_ENCODING | PKCS_7_ASN_ENCODING, X509_ECC_PRIVATE_KEY, IGNORED_PTR_ARG, IGNORED_NUM_ARG, 0, NULL, IGNORED_PTR_ARG, IGNORED_PTR_ARG)); /*this is asking "how big is the decoded private key? (from binary)*/
    STRICT_EXPECTED_CALL(CertCreateCertificateContext(X509_ASN_ENCODING | PKCS_7_ASN_ENCODING, IGNORED_PTR_ARG, IGNORED_NUM_ARG)); /*create a certificate context from an encoded certificate*/

    STRICT_EXPECTED_CALL(gballoc_malloc(IGNORED_NUM_ARG));
    STRICT_EXPECTED_CALL(NCryptOpenStorageProvider(IGNORED_PTR_ARG, MS_KEY_STORAGE_PROVIDER, 0))
        .IgnoreArgument_pszProviderName();
    STRICT_EXPECTED_CALL(NCryptImportKey((NCRYPT_PROV_HANDLE)IGNORED_PTR_ARG, (NCRYPT_KEY_HANDLE)IGNORED_PTR_ARG, IGNORED_PTR_ARG, IGNORED_PTR_ARG, IGNORED_PTR_ARG, IGNORED_PTR_ARG, IGNORED_NUM_ARG, NCRYPT_OVERWRITE_KEY_FLAG))
        .IgnoreArgument_hProvider()
        .IgnoreArgument_hImportKey();
    STRICT_EXPECTED_CALL(NCryptFreeObject((HCRYPTKEY)IGNORED_PTR_ARG))
        .IgnoreArgument_hObject();
    STRICT_EXPECTED_CALL(NCryptFreeObject((HCRYPTKEY)IGNORED_PTR_ARG))
        .IgnoreArgument_hObject();

    STRICT_EXPECTED_CALL(CertSetCertificateContextProperty(IGNORED_PTR_ARG, CERT_KEY_PROV_INFO_PROP_ID, 0, IGNORED_PTR_ARG)); /*give the private key*/
    STRICT_EXPECTED_CALL(gballoc_free(IGNORED_PTR_ARG));
    STRICT_EXPECTED_CALL(gballoc_free(IGNORED_PTR_ARG));
    STRICT_EXPECTED_CALL(gballoc_free(IGNORED_PTR_ARG));
    STRICT_EXPECTED_CALL(gballoc_free(IGNORED_PTR_ARG));
}
Esempio n. 2
0
/**
 *
 * save public or private key to PEM format
 *
 * ifile   : name of file to write PEM encoded key
 * pemType : type of key being saved
 * rsa     : RSA object with public and private keys
 *
 */
int rsa_read_key(RSA* rsa,
                 const char* ifile, int pemType)
{
    LPVOID                  derData, keyData;
    PCRYPT_PRIVATE_KEY_INFO pki = 0;
    DWORD                   pkiLen, derLen, keyLen;
    BOOL                    ok = FALSE;
    // decode base64 string ignoring headers
    derData = rsa_read_pem(ifile, &derLen);

    if (derData != NULL) {
        // decode DER
        // is it a public key?
        if (pemType == RSA_PUBLIC_KEY) {
            if (CryptDecodeObjectEx(
                    X509_ASN_ENCODING | PKCS_7_ASN_ENCODING,
                    X509_PUBLIC_KEY_INFO, derData, derLen,
                    CRYPT_DECODE_ALLOC_FLAG, NULL,
                    &keyData, &keyLen)) {
                // if decode ok, import it
                ok = CryptImportPublicKeyInfo(rsa->prov, X509_ASN_ENCODING,
                                              (PCERT_PUBLIC_KEY_INFO)keyData, &rsa->pubkey);
                // release allocated memory
                LocalFree(keyData);
            }
        } else {
            // convert the PKCS#8 data to private key info
            if (CryptDecodeObjectEx(
                    X509_ASN_ENCODING | PKCS_7_ASN_ENCODING,
                    PKCS_PRIVATE_KEY_INFO, derData, derLen,
                    CRYPT_DECODE_ALLOC_FLAG,
                    NULL, &pki, &pkiLen)) {
                // then convert the private key to private key blob
                if (CryptDecodeObjectEx(
                        X509_ASN_ENCODING | PKCS_7_ASN_ENCODING,
                        PKCS_RSA_PRIVATE_KEY,
                        pki->PrivateKey.pbData,
                        pki->PrivateKey.cbData,
                        CRYPT_DECODE_ALLOC_FLAG, NULL,
                        &keyData, &keyLen)) {
                    // if decode ok, import it
                    ok = CryptImportKey(rsa->prov, keyData, keyLen,
                                        0, CRYPT_EXPORTABLE, &rsa->privkey);
                    // release data
                    LocalFree(keyData);
                }

                // release private key info
                LocalFree(pki);
            }
        }

        xfree(derData);
    }

    return ok;
}
Esempio n. 3
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. 4
0
static BOOL CRYPT_FormatCPS(DWORD dwCertEncodingType,
 DWORD dwFormatStrType, const BYTE *pbEncoded, DWORD cbEncoded,
 WCHAR *str, DWORD *pcchStr)
{
    BOOL ret;
    DWORD size, charsNeeded = 1;
    CERT_NAME_VALUE *cpsValue;

    if ((ret = CryptDecodeObjectEx(dwCertEncodingType, X509_UNICODE_ANY_STRING,
     pbEncoded, cbEncoded, CRYPT_DECODE_ALLOC_FLAG, NULL, &cpsValue, &size)))
    {
        LPCWSTR sep;
        DWORD sepLen;

        if (dwFormatStrType & CRYPT_FORMAT_STR_MULTI_LINE)
            sep = crlf;
        else
            sep = commaSep;

        sepLen = strlenW(sep);

        if (dwFormatStrType & CRYPT_FORMAT_STR_MULTI_LINE)
        {
            charsNeeded += 3 * strlenW(indent);
            if (str && *pcchStr >= charsNeeded)
            {
                strcpyW(str, indent);
                str += strlenW(indent);
                strcpyW(str, indent);
                str += strlenW(indent);
                strcpyW(str, indent);
                str += strlenW(indent);
            }
        }
        charsNeeded += cpsValue->Value.cbData / sizeof(WCHAR);
        if (str && *pcchStr >= charsNeeded)
        {
            strcpyW(str, (LPWSTR)cpsValue->Value.pbData);
            str += cpsValue->Value.cbData / sizeof(WCHAR);
        }
        charsNeeded += sepLen;
        if (str && *pcchStr >= charsNeeded)
        {
            strcpyW(str, sep);
            str += sepLen;
        }
        LocalFree(cpsValue);
        if (!str)
            *pcchStr = charsNeeded;
        else if (*pcchStr < charsNeeded)
        {
            *pcchStr = charsNeeded;
            SetLastError(ERROR_MORE_DATA);
            ret = FALSE;
        }
        else
            *pcchStr = charsNeeded;
    }
    return ret;
}
Esempio n. 5
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. 6
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;
}
Esempio n. 7
0
static BOOL WINTRUST_GetTimeFromCounterSigner(
 const CMSG_CMS_SIGNER_INFO *counterSignerInfo, FILETIME *time)
{
    DWORD i;
    BOOL foundTimeStamp = FALSE;

    for (i = 0; !foundTimeStamp && i < counterSignerInfo->AuthAttrs.cAttr; i++)
    {
        if (!strcmp(counterSignerInfo->AuthAttrs.rgAttr[i].pszObjId,
         szOID_RSA_signingTime))
        {
            const CRYPT_ATTRIBUTE *attr =
             &counterSignerInfo->AuthAttrs.rgAttr[i];
            DWORD j;

            for (j = 0; !foundTimeStamp && j < attr->cValue; j++)
            {
                static const DWORD encoding = X509_ASN_ENCODING |
                 PKCS_7_ASN_ENCODING;
                DWORD size = sizeof(FILETIME);

                foundTimeStamp = CryptDecodeObjectEx(encoding,
                 X509_CHOICE_OF_TIME,
                 attr->rgValue[j].pbData, attr->rgValue[j].cbData, 0, NULL,
                 time, &size);
            }
        }
    }
    return foundTimeStamp;
}
static void setup_x509_schannel_create_mocks(void)
{
    STRICT_EXPECTED_CALL(gballoc_malloc(IGNORED_NUM_ARG)); /*this is creating the handle storage space*/
    STRICT_EXPECTED_CALL(CryptStringToBinaryA("certificate", 0, CRYPT_STRING_ANY, NULL, IGNORED_PTR_ARG, NULL, NULL)); /*this is asking for "how big is the certificate binary size?"*/
    STRICT_EXPECTED_CALL(gballoc_malloc(IGNORED_NUM_ARG)); /*this is creating the binary storage for the certificate*/
    STRICT_EXPECTED_CALL(CryptStringToBinaryA("certificate", 0, CRYPT_STRING_ANY, IGNORED_PTR_ARG, IGNORED_PTR_ARG, NULL, NULL)); /*this is asking for "fill in the certificate in this binary buffer"*/
    STRICT_EXPECTED_CALL(CryptStringToBinaryA("private key", 0, CRYPT_STRING_ANY, NULL, IGNORED_PTR_ARG, NULL, NULL)); /*this is asking for "how big is the private key binary size?"*/
    STRICT_EXPECTED_CALL(gballoc_malloc(IGNORED_NUM_ARG)); /*this is creating the binary storage for the private key*/
    STRICT_EXPECTED_CALL(CryptStringToBinaryA("private key", 0, CRYPT_STRING_ANY, IGNORED_PTR_ARG, IGNORED_PTR_ARG, NULL, NULL)); /*this is asking for "fill in the private key in this binary buffer"*/
    STRICT_EXPECTED_CALL(CryptDecodeObjectEx(X509_ASN_ENCODING | PKCS_7_ASN_ENCODING, PKCS_RSA_PRIVATE_KEY, IGNORED_PTR_ARG, IGNORED_NUM_ARG, 0, NULL, NULL, IGNORED_PTR_ARG)); /*this is asking "how big is the decoded private key? (from binary)*/
    STRICT_EXPECTED_CALL(gballoc_malloc(IGNORED_NUM_ARG)); /*this is allocating space for the decoded private key*/
    STRICT_EXPECTED_CALL(CryptDecodeObjectEx(X509_ASN_ENCODING | PKCS_7_ASN_ENCODING, PKCS_RSA_PRIVATE_KEY, IGNORED_PTR_ARG, IGNORED_NUM_ARG, 0, NULL, IGNORED_PTR_ARG, IGNORED_PTR_ARG)); /*this is asking "how big is the decoded private key? (from binary)*/
    STRICT_EXPECTED_CALL(CertCreateCertificateContext(X509_ASN_ENCODING | PKCS_7_ASN_ENCODING, IGNORED_PTR_ARG, IGNORED_NUM_ARG)); /*create a certificate context from an encoded certificate*/
    STRICT_EXPECTED_CALL(CryptAcquireContextA(IGNORED_PTR_ARG, NULL, MS_ENH_RSA_AES_PROV, PROV_RSA_AES, CRYPT_VERIFYCONTEXT)); /*this is acquire a handle to a key container within a cryptographic service provider*/
    STRICT_EXPECTED_CALL(CryptImportKey((HCRYPTPROV)IGNORED_PTR_ARG, IGNORED_PTR_ARG, IGNORED_NUM_ARG, (HCRYPTKEY)NULL, 0, IGNORED_PTR_ARG)) /*tranferring the key from the blob to the cryptrographic key provider*/
        .IgnoreArgument_hProv();
    STRICT_EXPECTED_CALL(CertSetCertificateContextProperty(IGNORED_PTR_ARG, CERT_KEY_PROV_HANDLE_PROP_ID, 0, IGNORED_PTR_ARG)); /*give the private key*/
    STRICT_EXPECTED_CALL(gballoc_free(IGNORED_PTR_ARG));
    STRICT_EXPECTED_CALL(gballoc_free(IGNORED_PTR_ARG));
    STRICT_EXPECTED_CALL(gballoc_free(IGNORED_PTR_ARG));
}
Esempio n. 9
0
static int
_libssh2_wincng_asn_decode(unsigned char *pbEncoded,
                           unsigned long cbEncoded,
                           LPCSTR lpszStructType,
                           unsigned char **ppbDecoded,
                           unsigned long *pcbDecoded)
{
    unsigned char *pbDecoded = NULL;
    unsigned long cbDecoded = 0;
    int ret;

    ret = CryptDecodeObjectEx(X509_ASN_ENCODING | PKCS_7_ASN_ENCODING,
                              lpszStructType,
                              pbEncoded, cbEncoded, 0, NULL,
                              NULL, &cbDecoded);
    if (!ret) {
        return -1;
    }

    pbDecoded = malloc(cbDecoded);
    if (!pbDecoded) {
        return -1;
    }

    ret = CryptDecodeObjectEx(X509_ASN_ENCODING | PKCS_7_ASN_ENCODING,
                              lpszStructType,
                              pbEncoded, cbEncoded, 0, NULL,
                              pbDecoded, &cbDecoded);
    if (!ret) {
        free(pbDecoded);
        return -1;
    }


    *ppbDecoded = pbDecoded;
    *pcbDecoded = cbDecoded;

    return 0;
}
Esempio n. 10
0
File: str.c Progetto: 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;
}
Esempio n. 11
0
static FILETIME WINTRUST_GetTimeFromSigner(const CRYPT_PROVIDER_DATA *data,
 const CMSG_SIGNER_INFO *signerInfo)
{
    DWORD i;
    FILETIME time;
    BOOL foundTimeStamp = FALSE;

    for (i = 0; !foundTimeStamp && i < signerInfo->UnauthAttrs.cAttr; i++)
    {
        if (!strcmp(signerInfo->UnauthAttrs.rgAttr[i].pszObjId,
         szOID_RSA_counterSign))
        {
            const CRYPT_ATTRIBUTE *attr = &signerInfo->UnauthAttrs.rgAttr[i];
            DWORD j;

            for (j = 0; j < attr->cValue; j++)
            {
                static const DWORD encoding = X509_ASN_ENCODING |
                 PKCS_7_ASN_ENCODING;
                CMSG_CMS_SIGNER_INFO *counterSignerInfo;
                DWORD size;
                BOOL ret = CryptDecodeObjectEx(encoding, CMS_SIGNER_INFO,
                 attr->rgValue[j].pbData, attr->rgValue[j].cbData,
                 CRYPT_DECODE_ALLOC_FLAG, NULL, &counterSignerInfo, &size);
                if (ret)
                {
                    /* FIXME: need to verify countersigner signature too */
                    foundTimeStamp = WINTRUST_GetTimeFromCounterSigner(
                     counterSignerInfo, &time);
                    LocalFree(counterSignerInfo);
                }
            }
        }
    }
    if (!foundTimeStamp)
    {
        TRACE("returning system time %s\n",
         filetime_to_str(&data->sftSystemTime));
        time = data->sftSystemTime;
    }
    else
        TRACE("returning time from message %s\n", filetime_to_str(&time));
    return time;
}
Esempio n. 12
0
PCCRL_CONTEXT WINAPI CertCreateCRLContext(DWORD dwCertEncodingType,
        const BYTE* pbCrlEncoded, DWORD cbCrlEncoded)
{
    PCRL_CONTEXT crl = NULL;
    BOOL ret;
    PCRL_INFO crlInfo = NULL;
    DWORD size = 0;

    TRACE("(%08x, %p, %d)\n", dwCertEncodingType, pbCrlEncoded,
          cbCrlEncoded);

    if ((dwCertEncodingType & CERT_ENCODING_TYPE_MASK) != X509_ASN_ENCODING)
    {
        SetLastError(E_INVALIDARG);
        return NULL;
    }
    ret = CryptDecodeObjectEx(dwCertEncodingType, X509_CERT_CRL_TO_BE_SIGNED,
                              pbCrlEncoded, cbCrlEncoded, CRYPT_DECODE_ALLOC_FLAG, NULL,
                              &crlInfo, &size);
    if (ret)
    {
        BYTE *data = NULL;

        crl = Context_CreateDataContext(sizeof(CRL_CONTEXT));
        if (!crl)
            goto end;
        data = CryptMemAlloc(cbCrlEncoded);
        if (!data)
        {
            CertFreeCRLContext(crl);
            crl = NULL;
            goto end;
        }
        memcpy(data, pbCrlEncoded, cbCrlEncoded);
        crl->dwCertEncodingType = dwCertEncodingType;
        crl->pbCrlEncoded       = data;
        crl->cbCrlEncoded       = cbCrlEncoded;
        crl->pCrlInfo           = crlInfo;
        crl->hCertStore         = 0;
    }

end:
    return crl;
}
Esempio n. 13
0
File: crl.c Progetto: AlexSteel/wine
PCCRL_CONTEXT WINAPI CertCreateCRLContext(DWORD dwCertEncodingType,
 const BYTE* pbCrlEncoded, DWORD cbCrlEncoded)
{
    crl_t *crl = NULL;
    BOOL ret;
    PCRL_INFO crlInfo = NULL;
    BYTE *data = NULL;
    DWORD size = 0;

    TRACE("(%08x, %p, %d)\n", dwCertEncodingType, pbCrlEncoded,
     cbCrlEncoded);

    if ((dwCertEncodingType & CERT_ENCODING_TYPE_MASK) != X509_ASN_ENCODING)
    {
        SetLastError(E_INVALIDARG);
        return NULL;
    }
    ret = CryptDecodeObjectEx(dwCertEncodingType, X509_CERT_CRL_TO_BE_SIGNED,
     pbCrlEncoded, cbCrlEncoded, CRYPT_DECODE_ALLOC_FLAG, NULL,
     &crlInfo, &size);
    if (!ret)
        return NULL;

    crl = (crl_t*)Context_CreateDataContext(sizeof(CRL_CONTEXT), &crl_vtbl, &empty_store);
    if (!crl)
        return NULL;

    data = CryptMemAlloc(cbCrlEncoded);
    if (!data)
    {
        Context_Release(&crl->base);
        return NULL;
    }

    memcpy(data, pbCrlEncoded, cbCrlEncoded);
    crl->ctx.dwCertEncodingType = dwCertEncodingType;
    crl->ctx.pbCrlEncoded       = data;
    crl->ctx.cbCrlEncoded       = cbCrlEncoded;
    crl->ctx.pCrlInfo           = crlInfo;
    crl->ctx.hCertStore         = &empty_store;

    return &crl->ctx;
}
Esempio n. 14
0
File: crl.c Progetto: AlexSteel/wine
static context_t *CRL_clone(context_t *context, WINECRYPT_CERTSTORE *store, BOOL use_link)
{
    crl_t *crl;

    if(use_link) {
        crl = (crl_t*)Context_CreateLinkContext(sizeof(CRL_CONTEXT), context, store);
        if(!crl)
            return NULL;
    }else {
        const crl_t *cloned = (const crl_t*)context;
        DWORD size = 0;
        BOOL res;

        crl = (crl_t*)Context_CreateDataContext(sizeof(CRL_CONTEXT), &crl_vtbl, store);
        if(!crl)
            return NULL;

        Context_CopyProperties(&crl->ctx, &cloned->ctx);

        crl->ctx.dwCertEncodingType = cloned->ctx.dwCertEncodingType;
        crl->ctx.pbCrlEncoded = CryptMemAlloc(cloned->ctx.cbCrlEncoded);
        memcpy(crl->ctx.pbCrlEncoded, cloned->ctx.pbCrlEncoded, cloned->ctx.cbCrlEncoded);
        crl->ctx.cbCrlEncoded = cloned->ctx.cbCrlEncoded;

        /* FIXME: We don't need to decode the object here, we could just clone crl info. */
        res = CryptDecodeObjectEx(crl->ctx.dwCertEncodingType, X509_CERT_CRL_TO_BE_SIGNED,
         crl->ctx.pbCrlEncoded, crl->ctx.cbCrlEncoded, CRYPT_DECODE_ALLOC_FLAG, NULL,
         &crl->ctx.pCrlInfo, &size);
        if(!res) {
            CertFreeCRLContext(&crl->ctx);
            return NULL;
        }
    }

    crl->ctx.hCertStore = store;
    return &crl->base;
}
Esempio n. 15
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. 16
0
File: str.c Progetto: 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;
}
void ca_generate_root_ca_cert_t::generate_ca_cert_clicked(){
	GIE_QT_DEF_EXCEPTION_GUARD_BEGIN

		stcrypt::cert_name_t cert_subject_name;


		#define STCRYPT_TOYCA_CP_NAME(x) { auto str = ui.x##_edit->text().toStdWString(); cert_subject_name.set_##x( std::move(str) ); }

		STCRYPT_TOYCA_CP_NAME(common_name);
 		STCRYPT_TOYCA_CP_NAME(country_name);
 		STCRYPT_TOYCA_CP_NAME(locality_name);
 		STCRYPT_TOYCA_CP_NAME(organization_name);
 		STCRYPT_TOYCA_CP_NAME(organization_unit_name);
		STCRYPT_TOYCA_CP_NAME(state_or_province_name);
		STCRYPT_TOYCA_CP_NAME(email_name);

		#undef STCRYPT_TOYCA_CP_NAME

		// generate key pair
		NCRYPT_PROV_HANDLE cng_provider=0;
		NCRYPT_KEY_HANDLE  cng_n_key_pair=0;
		
		auto status = NCryptOpenStorageProvider(&cng_provider, CNG_STCRYPT_KEYSTORAGE, 0);
		STCRYPT_CHECK(!FAILED(status));
		BOOST_SCOPE_EXIT((&cng_provider)) { auto const status = NCryptFreeObject (cng_provider);  assert( !FAILED(status) ); } BOOST_SCOPE_EXIT_END

		boost::uuids::uuid const key_container_id( (boost::uuids::random_generator()()) );
		auto const& key_pair_container_name = boost::lexical_cast<std::wstring>( key_container_id );

		status = NCryptCreatePersistedKey(cng_provider, &cng_n_key_pair, NCNG_DSTU4145, key_pair_container_name.c_str(), AT_KEYEXCHANGE, 0/*NCRYPT_OVERWRITE_KEY_FLAG*/);
		STCRYPT_CHECK(!FAILED(status));
		BOOST_SCOPE_EXIT((&cng_n_key_pair)) { auto const status = NCryptFreeObject (cng_n_key_pair);  assert( !FAILED(status) ); } BOOST_SCOPE_EXIT_END

		status = NCryptFinalizeKey(cng_n_key_pair, 0);
		STCRYPT_CHECK(!FAILED(status));

		auto const& to_be_signed_cert_blob = ms_cert::create_req_blob(cert_subject_name, cng_n_key_pair, cert_subject_name);

		DWORD size;
		STCRYPT_CHECK( CryptDecodeObjectEx(X509_ASN_ENCODING, X509_CERT_TO_BE_SIGNED, reinterpret_cast<BYTE const*> (to_be_signed_cert_blob.data()), to_be_signed_cert_blob.size(), CRYPT_DECODE_TO_BE_SIGNED_FLAG, 0, 0, &size) );
		STCRYPT_CHECK(size!=0);

		std::vector<unsigned char> to_be_signed_cert_blob_combined(size);
		STCRYPT_CHECK( CryptDecodeObjectEx(X509_ASN_ENCODING, X509_CERT_TO_BE_SIGNED, reinterpret_cast<BYTE const*> (to_be_signed_cert_blob.data()), to_be_signed_cert_blob.size(), CRYPT_DECODE_TO_BE_SIGNED_FLAG, 0, to_be_signed_cert_blob_combined.data(), &size) );
		to_be_signed_cert_blob_combined.resize(size);

		CERT_INFO* const cert_to_be_signed = static_cast<CERT_INFO*>( static_cast<void*>( to_be_signed_cert_blob_combined.data() ) );

		// do sign
		CRYPT_ALGORITHM_IDENTIFIER signature_alg={OID_G34311_DSTU4145_SIGN,0};

		DWORD encoded_cert_size = 0;
 		if( !CryptSignAndEncodeCertificate(cng_n_key_pair, 0, X509_ASN_ENCODING, X509_CERT_TO_BE_SIGNED, cert_to_be_signed, &signature_alg, 0, 0, &encoded_cert_size) ){ //TODO: this CryptSignAndEncodeCertificate leaks memory
 			STCRYPT_UNEXPECTED();
 		}
 		STCRYPT_CHECK(encoded_cert_size!=0);
 
 		std::vector<BYTE> signed_certificate(encoded_cert_size);
 		if( !CryptSignAndEncodeCertificate(cng_n_key_pair, 0, X509_ASN_ENCODING, X509_CERT_TO_BE_SIGNED, cert_to_be_signed, &signature_alg, 0, signed_certificate.data(), &encoded_cert_size) ){
 			STCRYPT_UNEXPECTED();
 		}
 		signed_certificate.resize(encoded_cert_size);

		// context from signed blob
		ms_cert::pccert_context_t signed_cert_context( CertCreateCertificateContext (X509_ASN_ENCODING, reinterpret_cast<BYTE const*>( signed_certificate.data() ), signed_certificate.size() ) );
		STCRYPT_CHECK( signed_cert_context );

		// assign private key container name
		CRYPT_KEY_PROV_INFO key_prov_info = {0};
		key_prov_info.pwszContainerName = const_cast<wchar_t*>( key_pair_container_name.c_str() );
		key_prov_info.pwszProvName = CNG_STCRYPT_KEYSTORAGE;
		key_prov_info.dwProvType = 0;
		key_prov_info.dwFlags = 0;
		key_prov_info.cProvParam = 0;
		key_prov_info.rgProvParam = 0;
		key_prov_info.dwKeySpec = 0;

		STCRYPT_CHECK( CertSetCertificateContextProperty(signed_cert_context.handle(), CERT_KEY_PROV_INFO_PROP_ID, 0, &key_prov_info) );
		STCRYPT_CHECK( CryptUIDlgViewContext (CERT_STORE_CERTIFICATE_CONTEXT, signed_cert_context.handle(), this->winId(), L"Generated CA certificate [NOT YET INSTALLED]", 0, 0) );

		ms_cert::import_into_ms_store2(signed_cert_context.handle(), L"ROOT");

		STCRYPT_CHECK( CryptUIDlgViewContext (CERT_STORE_CERTIFICATE_CONTEXT, signed_cert_context.handle(), this->winId(), L"Generated CA certificate", 0, 0) );

		toy_ca::initialize_accept_requests_mode( dynamic_cast<QMainWindow*>( this->parent() ), std::move(signed_cert_context) );

	GIE_QT_DEF_EXCEPTION_GUARD_END
}
Esempio n. 18
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. 19
0
DWORD WINAPI CertNameToStrW(DWORD dwCertEncodingType, PCERT_NAME_BLOB pName,
 DWORD dwStrType, LPWSTR psz, DWORD csz)
{
    static const DWORD unsupportedFlags = CERT_NAME_STR_NO_QUOTING_FLAG |
     CERT_NAME_STR_REVERSE_FLAG | CERT_NAME_STR_ENABLE_T61_UNICODE_FLAG;
    static const WCHAR commaSep[] = { ',',' ',0 };
    static const WCHAR semiSep[] = { ';',' ',0 };
    static const WCHAR crlfSep[] = { '\r','\n',0 };
    static const WCHAR plusSep[] = { ' ','+',' ',0 };
    static const WCHAR spaceSep[] = { ' ',0 };
    DWORD ret = 0, bytes = 0;
    BOOL bRet;
    CERT_NAME_INFO *info;

    TRACE("(%ld, %p, %08lx, %p, %ld)\n", dwCertEncodingType, pName, dwStrType,
     psz, csz);
    if (dwStrType & unsupportedFlags)
        FIXME("unsupported flags: %08lx\n", dwStrType & unsupportedFlags);

    bRet = CryptDecodeObjectEx(dwCertEncodingType, X509_NAME, pName->pbData,
     pName->cbData, CRYPT_DECODE_ALLOC_FLAG, NULL, &info, &bytes);
    if (bRet)
    {
        DWORD i, j, sepLen, rdnSepLen;
        LPCWSTR sep, rdnSep;

        if (dwStrType & CERT_NAME_STR_SEMICOLON_FLAG)
            sep = semiSep;
        else if (dwStrType & CERT_NAME_STR_CRLF_FLAG)
            sep = crlfSep;
        else
            sep = commaSep;
        sepLen = lstrlenW(sep);
        if (dwStrType & CERT_NAME_STR_NO_PLUS_FLAG)
            rdnSep = spaceSep;
        else
            rdnSep = plusSep;
        rdnSepLen = lstrlenW(rdnSep);
        for (i = 0; (!psz || ret < csz) && i < info->cRDN; i++)
        {
            for (j = 0; (!psz || ret < csz) && j < info->rgRDN[i].cRDNAttr; j++)
            {
                DWORD chars;
                LPCSTR prefixA = NULL;
                LPCWSTR prefixW = NULL;

                if ((dwStrType & 0x000000ff) == CERT_OID_NAME_STR)
                    prefixA = info->rgRDN[i].rgRDNAttr[j].pszObjId;
                else if ((dwStrType & 0x000000ff) == CERT_X500_NAME_STR)
                {
                    PCCRYPT_OID_INFO oidInfo = CryptFindOIDInfo(
                     CRYPT_OID_INFO_OID_KEY,
                     info->rgRDN[i].rgRDNAttr[j].pszObjId,
                     CRYPT_RDN_ATTR_OID_GROUP_ID);

                    if (oidInfo)
                        prefixW = oidInfo->pwszName;
                    else
                        prefixA = info->rgRDN[i].rgRDNAttr[j].pszObjId;
                }
                if (prefixW)
                {
                    /* - 1 is needed to account for the NULL terminator. */
                    chars = CRYPT_AddPrefixW(prefixW,
                     psz ? psz + ret : NULL, psz ? csz - ret - 1 : 0);
                    ret += chars;
                    csz -= chars;
                }
                else if (prefixA)
                {
                    /* - 1 is needed to account for the NULL terminator. */
                    chars = CRYPT_AddPrefixAToW(prefixA,
                     psz ? psz + ret : NULL, psz ? csz - ret - 1 : 0);
                    ret += chars;
                    csz -= chars;
                }
                /* FIXME: handle quoting */
                chars = CertRDNValueToStrW(
                 info->rgRDN[i].rgRDNAttr[j].dwValueType, 
                 &info->rgRDN[i].rgRDNAttr[j].Value, psz ? psz + ret : NULL,
                 psz ? csz - ret : 0);
                if (chars)
                    ret += chars - 1;
                if (j < info->rgRDN[i].cRDNAttr - 1)
                {
                    if (psz && ret < csz - rdnSepLen - 1)
                        memcpy(psz + ret, rdnSep, rdnSepLen * sizeof(WCHAR));
                    ret += rdnSepLen;
                }
            }
            if (i < info->cRDN - 1)
            {
                if (psz && ret < csz - sepLen - 1)
                    memcpy(psz + ret, sep, sepLen * sizeof(WCHAR));
                ret += sepLen;
            }
        }
        LocalFree(info);
    }
    if (psz && csz)
    {
        *(psz + ret) = '\0';
        csz--;
        ret++;
    }
    else
        ret++;
    TRACE("Returning %s\n", debugstr_w(psz));
    return ret;
}
Esempio n. 20
0
DWORD WINAPI CertNameToStrA(DWORD dwCertEncodingType, PCERT_NAME_BLOB pName,
 DWORD dwStrType, LPSTR psz, DWORD csz)
{
    static const DWORD unsupportedFlags = CERT_NAME_STR_NO_QUOTING_FLAG |
     CERT_NAME_STR_REVERSE_FLAG | CERT_NAME_STR_ENABLE_T61_UNICODE_FLAG;
    static const char commaSep[] = ", ";
    static const char semiSep[] = "; ";
    static const char crlfSep[] = "\r\n";
    static const char plusSep[] = " + ";
    static const char spaceSep[] = " ";
    DWORD ret = 0, bytes = 0;
    BOOL bRet;
    CERT_NAME_INFO *info;

    TRACE("(%ld, %p, %08lx, %p, %ld)\n", dwCertEncodingType, pName, dwStrType,
     psz, csz);
    if (dwStrType & unsupportedFlags)
        FIXME("unsupported flags: %08lx\n", dwStrType & unsupportedFlags);

    bRet = CryptDecodeObjectEx(dwCertEncodingType, X509_NAME, pName->pbData,
     pName->cbData, CRYPT_DECODE_ALLOC_FLAG, NULL, &info, &bytes);
    if (bRet)
    {
        DWORD i, j, sepLen, rdnSepLen;
        LPCSTR sep, rdnSep;

        if (dwStrType & CERT_NAME_STR_SEMICOLON_FLAG)
            sep = semiSep;
        else if (dwStrType & CERT_NAME_STR_CRLF_FLAG)
            sep = crlfSep;
        else
            sep = commaSep;
        sepLen = strlen(sep);
        if (dwStrType & CERT_NAME_STR_NO_PLUS_FLAG)
            rdnSep = spaceSep;
        else
            rdnSep = plusSep;
        rdnSepLen = strlen(rdnSep);
        for (i = 0; (!psz || ret < csz) && i < info->cRDN; i++)
        {
            for (j = 0; (!psz || ret < csz) && j < info->rgRDN[i].cRDNAttr; j++)
            {
                DWORD chars;
                char prefixBuf[10]; /* big enough for GivenName */
                LPCSTR prefix = NULL;

                if ((dwStrType & 0x000000ff) == CERT_OID_NAME_STR)
                    prefix = info->rgRDN[i].rgRDNAttr[j].pszObjId;
                else if ((dwStrType & 0x000000ff) == CERT_X500_NAME_STR)
                {
                    PCCRYPT_OID_INFO oidInfo = CryptFindOIDInfo(
                     CRYPT_OID_INFO_OID_KEY,
                     info->rgRDN[i].rgRDNAttr[j].pszObjId,
                     CRYPT_RDN_ATTR_OID_GROUP_ID);

                    if (oidInfo)
                    {
                        WideCharToMultiByte(CP_ACP, 0, oidInfo->pwszName, -1,
                         prefixBuf, sizeof(prefixBuf), NULL, NULL);
                        prefix = prefixBuf;
                    }
                    else
                        prefix = info->rgRDN[i].rgRDNAttr[j].pszObjId;
                }
                if (prefix)
                {
                    /* - 1 is needed to account for the NULL terminator. */
                    chars = CRYPT_AddPrefixA(prefix,
                     psz ? psz + ret : NULL, psz ? csz - ret - 1 : 0);
                    ret += chars;
                    csz -= chars;
                }
                /* FIXME: handle quoting */
                chars = CertRDNValueToStrA(
                 info->rgRDN[i].rgRDNAttr[j].dwValueType, 
                 &info->rgRDN[i].rgRDNAttr[j].Value, psz ? psz + ret : NULL,
                 psz ? csz - ret : 0);
                if (chars)
                    ret += chars - 1;
                if (j < info->rgRDN[i].cRDNAttr - 1)
                {
                    if (psz && ret < csz - rdnSepLen - 1)
                        memcpy(psz + ret, rdnSep, rdnSepLen);
                    ret += rdnSepLen;
                }
            }
            if (i < info->cRDN - 1)
            {
                if (psz && ret < csz - sepLen - 1)
                    memcpy(psz + ret, sep, sepLen);
                ret += sepLen;
            }
        }
        LocalFree(info);
    }
    if (psz && csz)
    {
        *(psz + ret) = '\0';
        csz--;
        ret++;
    }
    else
        ret++;
    TRACE("Returning %s\n", debugstr_a(psz));
    return ret;
}
Esempio n. 21
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;
}
Esempio n. 22
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. 23
0
my_bool ma_schannel_load_private_key(MARIADB_PVIO *pvio, CERT_CONTEXT *ctx, char *key_file)
{
   DWORD der_buffer_len= 0;
   LPBYTE der_buffer= NULL;
   DWORD priv_key_len= 0;
   LPBYTE priv_key= NULL;
   HCRYPTPROV  crypt_prov= 0;
   HCRYPTKEY  crypt_key= 0;
   CERT_KEY_CONTEXT kpi={ 0 };
   my_bool rc= 0;

   /* load private key into der binary object */
   if (!(der_buffer= ma_schannel_load_pem(pvio, key_file, &der_buffer_len)))
     return 0;

   /* determine required buffer size for decoded private key */
   if (!CryptDecodeObjectEx(X509_ASN_ENCODING | PKCS_7_ASN_ENCODING,
                            PKCS_RSA_PRIVATE_KEY,
                            der_buffer, der_buffer_len,
                            0, NULL,
                            NULL, &priv_key_len))
   {
     ma_schannel_set_win_error(pvio);
     goto end;
   }

   /* allocate buffer for decoded private key */
   if (!(priv_key= LocalAlloc(0, priv_key_len)))
   {
     pvio->set_error(pvio->mysql, CR_OUT_OF_MEMORY, SQLSTATE_UNKNOWN, NULL);
     goto end;
   }

   /* decode */
   if (!CryptDecodeObjectEx(X509_ASN_ENCODING | PKCS_7_ASN_ENCODING,
                            PKCS_RSA_PRIVATE_KEY,
                            der_buffer, der_buffer_len,
                            0, NULL,
                            priv_key, &priv_key_len))
   {
     ma_schannel_set_win_error(pvio);
     goto end;
   }

   /* Acquire context */
   if (!CryptAcquireContext(&crypt_prov, NULL, MS_ENHANCED_PROV, PROV_RSA_FULL, CRYPT_VERIFYCONTEXT))
   {
     ma_schannel_set_win_error(pvio);
     goto end;
   }
   /* ... and import the private key */
   if (!CryptImportKey(crypt_prov, priv_key, priv_key_len, 0, 0, (HCRYPTKEY *)&crypt_key))
   {
     ma_schannel_set_win_error(pvio);
     goto end;
   }

   kpi.hCryptProv= crypt_prov;
   kpi.dwKeySpec = AT_KEYEXCHANGE;
   kpi.cbSize= sizeof(kpi);

   /* assign private key to certificate context */
   if (CertSetCertificateContextProperty(ctx, CERT_KEY_CONTEXT_PROP_ID, 0, &kpi))
     rc= 1;
   else
     ma_schannel_set_win_error(pvio);

end:
  if (der_buffer)
    LocalFree(der_buffer);
  if (priv_key)
  {
    if (crypt_key)
      CryptDestroyKey(crypt_key);
    LocalFree(priv_key);
  if (!rc)
    if (crypt_prov)
      CryptReleaseContext(crypt_prov, 0);
  }
  return rc;
}
Esempio n. 24
0
static BOOL CRYPT_FormatUserNotice(DWORD dwCertEncodingType,
 DWORD dwFormatStrType, const BYTE *pbEncoded, DWORD cbEncoded,
 WCHAR *str, DWORD *pcchStr)
{
    BOOL ret;
    DWORD size, charsNeeded = 1;
    CERT_POLICY_QUALIFIER_USER_NOTICE *notice;

    if ((ret = CryptDecodeObjectEx(dwCertEncodingType,
     X509_PKIX_POLICY_QUALIFIER_USERNOTICE, pbEncoded, cbEncoded,
     CRYPT_DECODE_ALLOC_FLAG, NULL, &notice, &size)))
    {
        static const WCHAR numFmt[] = { '%','d',0 };
        CERT_POLICY_QUALIFIER_NOTICE_REFERENCE *pNoticeRef =
         notice->pNoticeReference;
        LPCWSTR headingSep, sep;
        DWORD headingSepLen, sepLen;
        LPWSTR noticeRef, organization, noticeNum, noticeText;
        DWORD noticeRefLen, organizationLen, noticeNumLen, noticeTextLen;
        WCHAR noticeNumStr[11];

        noticeRefLen = LoadStringW(hInstance, IDS_NOTICE_REF,
         (LPWSTR)&noticeRef, 0);
        organizationLen = LoadStringW(hInstance, IDS_ORGANIZATION,
         (LPWSTR)&organization, 0);
        noticeNumLen = LoadStringW(hInstance, IDS_NOTICE_NUM,
         (LPWSTR)&noticeNum, 0);
        noticeTextLen = LoadStringW(hInstance, IDS_NOTICE_TEXT,
         (LPWSTR)&noticeText, 0);
        if (dwFormatStrType & CRYPT_FORMAT_STR_MULTI_LINE)
        {
            headingSep = colonCrlf;
            sep = crlf;
        }
        else
        {
            headingSep = colonSpace;
            sep = commaSep;
        }
        sepLen = strlenW(sep);
        headingSepLen = strlenW(headingSep);

        if (pNoticeRef)
        {
            DWORD k;
            LPCSTR src;

            if (dwFormatStrType & CRYPT_FORMAT_STR_MULTI_LINE)
            {
                charsNeeded += 3 * strlenW(indent);
                if (str && *pcchStr >= charsNeeded)
                {
                    strcpyW(str, indent);
                    str += strlenW(indent);
                    strcpyW(str, indent);
                    str += strlenW(indent);
                    strcpyW(str, indent);
                    str += strlenW(indent);
                }
            }
            charsNeeded += noticeRefLen;
            if (str && *pcchStr >= charsNeeded)
            {
                memcpy(str, noticeRef, noticeRefLen * sizeof(WCHAR));
                str += noticeRefLen;
            }
            charsNeeded += headingSepLen;
            if (str && *pcchStr >= charsNeeded)
            {
                strcpyW(str, headingSep);
                str += headingSepLen;
            }
            if (dwFormatStrType & CRYPT_FORMAT_STR_MULTI_LINE)
            {
                charsNeeded += 4 * strlenW(indent);
                if (str && *pcchStr >= charsNeeded)
                {
                    strcpyW(str, indent);
                    str += strlenW(indent);
                    strcpyW(str, indent);
                    str += strlenW(indent);
                    strcpyW(str, indent);
                    str += strlenW(indent);
                    strcpyW(str, indent);
                    str += strlenW(indent);
                }
            }
            charsNeeded += organizationLen;
            if (str && *pcchStr >= charsNeeded)
            {
                memcpy(str, organization, organizationLen * sizeof(WCHAR));
                str += organizationLen;
            }
            charsNeeded += strlen(pNoticeRef->pszOrganization);
            if (str && *pcchStr >= charsNeeded)
                for (src = pNoticeRef->pszOrganization; src && *src;
                 src++, str++)
                    *str = *src;
            charsNeeded += sepLen;
            if (str && *pcchStr >= charsNeeded)
            {
                strcpyW(str, sep);
                str += sepLen;
            }
            for (k = 0; k < pNoticeRef->cNoticeNumbers; k++)
            {
                if (dwFormatStrType & CRYPT_FORMAT_STR_MULTI_LINE)
                {
                    charsNeeded += 4 * strlenW(indent);
                    if (str && *pcchStr >= charsNeeded)
                    {
                        strcpyW(str, indent);
                        str += strlenW(indent);
                        strcpyW(str, indent);
                        str += strlenW(indent);
                        strcpyW(str, indent);
                        str += strlenW(indent);
                        strcpyW(str, indent);
                        str += strlenW(indent);
                    }
                }
                charsNeeded += noticeNumLen;
                if (str && *pcchStr >= charsNeeded)
                {
                    memcpy(str, noticeNum, noticeNumLen * sizeof(WCHAR));
                    str += noticeNumLen;
                }
                sprintfW(noticeNumStr, numFmt, k + 1);
                charsNeeded += strlenW(noticeNumStr);
                if (str && *pcchStr >= charsNeeded)
                {
                    strcpyW(str, noticeNumStr);
                    str += strlenW(noticeNumStr);
                }
                charsNeeded += sepLen;
                if (str && *pcchStr >= charsNeeded)
                {
                    strcpyW(str, sep);
                    str += sepLen;
                }
            }
        }
        if (notice->pszDisplayText)
        {
            if (dwFormatStrType & CRYPT_FORMAT_STR_MULTI_LINE)
            {
                charsNeeded += 3 * strlenW(indent);
                if (str && *pcchStr >= charsNeeded)
                {
                    strcpyW(str, indent);
                    str += strlenW(indent);
                    strcpyW(str, indent);
                    str += strlenW(indent);
                    strcpyW(str, indent);
                    str += strlenW(indent);
                }
            }
            charsNeeded += noticeTextLen;
            if (str && *pcchStr >= charsNeeded)
            {
                memcpy(str, noticeText, noticeTextLen * sizeof(WCHAR));
                str += noticeTextLen;
            }
            charsNeeded += strlenW(notice->pszDisplayText);
            if (str && *pcchStr >= charsNeeded)
            {
                strcpyW(str, notice->pszDisplayText);
                str += strlenW(notice->pszDisplayText);
            }
            charsNeeded += sepLen;
            if (str && *pcchStr >= charsNeeded)
            {
                strcpyW(str, sep);
                str += sepLen;
            }
        }
        LocalFree(notice);
        if (!str)
            *pcchStr = charsNeeded;
        else if (*pcchStr < charsNeeded)
        {
            *pcchStr = charsNeeded;
            SetLastError(ERROR_MORE_DATA);
            ret = FALSE;
        }
        else
            *pcchStr = charsNeeded;
    }
    return ret;
}
Esempio n. 25
0
/***********************************************************************
 *		FormatVerisignExtension (CRYPTDLG.@)
 */
BOOL WINAPI FormatVerisignExtension(DWORD dwCertEncodingType,
 DWORD dwFormatType, DWORD dwFormatStrType, void *pFormatStruct,
 LPCSTR lpszStructType, const BYTE *pbEncoded, DWORD cbEncoded, void *pbFormat,
 DWORD *pcbFormat)
{
    CERT_POLICIES_INFO *policies;
    DWORD size;
    BOOL ret = FALSE;

    if (!cbEncoded)
    {
        SetLastError(E_INVALIDARG);
        return FALSE;
    }
    if ((ret = CryptDecodeObjectEx(dwCertEncodingType, X509_CERT_POLICIES,
     pbEncoded, cbEncoded, CRYPT_DECODE_ALLOC_FLAG, NULL, &policies, &size)))
    {
        static const WCHAR numFmt[] = { '%','d',0 };
        DWORD charsNeeded = 1; /* space for NULL terminator */
        LPCWSTR headingSep, sep;
        DWORD headingSepLen, sepLen;
        WCHAR policyNum[11], policyQualifierNum[11];
        LPWSTR certPolicy, policyId, policyQualifierInfo, policyQualifierId;
        LPWSTR cps, userNotice, qualifier;
        DWORD certPolicyLen, policyIdLen, policyQualifierInfoLen;
        DWORD policyQualifierIdLen, cpsLen, userNoticeLen, qualifierLen;
        DWORD i;
        LPWSTR str = pbFormat;

        certPolicyLen = LoadStringW(hInstance, IDS_CERT_POLICY,
         (LPWSTR)&certPolicy, 0);
        policyIdLen = LoadStringW(hInstance, IDS_POLICY_ID, (LPWSTR)&policyId,
         0);
        policyQualifierInfoLen = LoadStringW(hInstance,
         IDS_POLICY_QUALIFIER_INFO, (LPWSTR)&policyQualifierInfo, 0);
        policyQualifierIdLen = LoadStringW(hInstance, IDS_POLICY_QUALIFIER_ID,
         (LPWSTR)&policyQualifierId, 0);
        cpsLen = LoadStringW(hInstance, IDS_CPS, (LPWSTR)&cps, 0);
        userNoticeLen = LoadStringW(hInstance, IDS_USER_NOTICE,
         (LPWSTR)&userNotice, 0);
        qualifierLen = LoadStringW(hInstance, IDS_QUALIFIER,
         (LPWSTR)&qualifier, 0);
        if (dwFormatStrType & CRYPT_FORMAT_STR_MULTI_LINE)
        {
            headingSep = colonCrlf;
            sep = crlf;
        }
        else
        {
            headingSep = colonSpace;
            sep = commaSep;
        }
        sepLen = strlenW(sep);
        headingSepLen = strlenW(headingSep);

        for (i = 0; ret && i < policies->cPolicyInfo; i++)
        {
            CERT_POLICY_INFO *policy = &policies->rgPolicyInfo[i];
            DWORD j;
            LPCSTR src;

            charsNeeded += 1; /* '['*/
            if (str && *pcbFormat >= charsNeeded * sizeof(WCHAR))
                *str++ = '[';
            sprintfW(policyNum, numFmt, i + 1);
            charsNeeded += strlenW(policyNum);
            if (str && *pcbFormat >= charsNeeded * sizeof(WCHAR))
            {
                strcpyW(str, policyNum);
                str += strlenW(policyNum);
            }
            charsNeeded += 1; /* ']'*/
            if (str && *pcbFormat >= charsNeeded * sizeof(WCHAR))
                *str++ = ']';
            charsNeeded += certPolicyLen;
            if (str && *pcbFormat >= charsNeeded * sizeof(WCHAR))
            {
                memcpy(str, certPolicy, certPolicyLen * sizeof(WCHAR));
                str += certPolicyLen;
            }
            charsNeeded += headingSepLen;
            if (str && *pcbFormat >= charsNeeded * sizeof(WCHAR))
            {
                strcpyW(str, headingSep);
                str += headingSepLen;
            }
            if (dwFormatStrType & CRYPT_FORMAT_STR_MULTI_LINE)
            {
                charsNeeded += strlenW(indent);
                if (str && *pcbFormat >= charsNeeded * sizeof(WCHAR))
                {
                    strcpyW(str, indent);
                    str += strlenW(indent);
                }
            }
            charsNeeded += policyIdLen;
            if (str && *pcbFormat >= charsNeeded * sizeof(WCHAR))
            {
                memcpy(str, policyId, policyIdLen * sizeof(WCHAR));
                str += policyIdLen;
            }
            charsNeeded += strlen(policy->pszPolicyIdentifier);
            if (str && *pcbFormat >= charsNeeded * sizeof(WCHAR))
            {
                for (src = policy->pszPolicyIdentifier; src && *src;
                 src++, str++)
                    *str = *src;
            }
            charsNeeded += sepLen;
            if (str && *pcbFormat >= charsNeeded * sizeof(WCHAR))
            {
                strcpyW(str, sep);
                str += sepLen;
            }
            for (j = 0; j < policy->cPolicyQualifier; j++)
            {
                CERT_POLICY_QUALIFIER_INFO *qualifierInfo =
                 &policy->rgPolicyQualifier[j];
                DWORD sizeRemaining;

                if (dwFormatStrType & CRYPT_FORMAT_STR_MULTI_LINE)
                {
                    charsNeeded += strlenW(indent);
                    if (str && *pcbFormat >= charsNeeded * sizeof(WCHAR))
                    {
                        strcpyW(str, indent);
                        str += strlenW(indent);
                    }
                }
                charsNeeded += 1; /* '['*/
                if (str && *pcbFormat >= charsNeeded * sizeof(WCHAR))
                    *str++ = '[';
                charsNeeded += strlenW(policyNum);
                if (str && *pcbFormat >= charsNeeded * sizeof(WCHAR))
                {
                    strcpyW(str, policyNum);
                    str += strlenW(policyNum);
                }
                charsNeeded += 1; /* ','*/
                if (str && *pcbFormat >= charsNeeded * sizeof(WCHAR))
                    *str++ = ',';
                sprintfW(policyQualifierNum, numFmt, j + 1);
                charsNeeded += strlenW(policyQualifierNum);
                if (str && *pcbFormat >= charsNeeded * sizeof(WCHAR))
                {
                    strcpyW(str, policyQualifierNum);
                    str += strlenW(policyQualifierNum);
                }
                charsNeeded += 1; /* ']'*/
                if (str && *pcbFormat >= charsNeeded * sizeof(WCHAR))
                    *str++ = ']';
                charsNeeded += policyQualifierInfoLen;
                if (str && *pcbFormat >= charsNeeded * sizeof(WCHAR))
                {
                    memcpy(str, policyQualifierInfo,
                     policyQualifierInfoLen * sizeof(WCHAR));
                    str += policyQualifierInfoLen;
                }
                charsNeeded += headingSepLen;
                if (str && *pcbFormat >= charsNeeded * sizeof(WCHAR))
                {
                    strcpyW(str, headingSep);
                    str += headingSepLen;
                }
                if (dwFormatStrType & CRYPT_FORMAT_STR_MULTI_LINE)
                {
                    charsNeeded += 2 * strlenW(indent);
                    if (str && *pcbFormat >= charsNeeded * sizeof(WCHAR))
                    {
                        strcpyW(str, indent);
                        str += strlenW(indent);
                        strcpyW(str, indent);
                        str += strlenW(indent);
                    }
                }
                charsNeeded += policyQualifierIdLen;
                if (str && *pcbFormat >= charsNeeded * sizeof(WCHAR))
                {
                    memcpy(str, policyQualifierId,
                     policyQualifierIdLen * sizeof(WCHAR));
                    str += policyQualifierIdLen;
                }
                if (!strcmp(qualifierInfo->pszPolicyQualifierId,
                 szOID_PKIX_POLICY_QUALIFIER_CPS))
                {
                    charsNeeded += cpsLen;
                    if (str && *pcbFormat >= charsNeeded * sizeof(WCHAR))
                    {
                        memcpy(str, cps, cpsLen * sizeof(WCHAR));
                        str += cpsLen;
                    }
                }
                else if (!strcmp(qualifierInfo->pszPolicyQualifierId,
                 szOID_PKIX_POLICY_QUALIFIER_USERNOTICE))
                {
                    charsNeeded += userNoticeLen;
                    if (str && *pcbFormat >= charsNeeded * sizeof(WCHAR))
                    {
                        memcpy(str, userNotice, userNoticeLen * sizeof(WCHAR));
                        str += userNoticeLen;
                    }
                }
                else
                {
                    charsNeeded += strlen(qualifierInfo->pszPolicyQualifierId);
                    if (str && *pcbFormat >= charsNeeded * sizeof(WCHAR))
                    {
                        for (src = qualifierInfo->pszPolicyQualifierId;
                         src && *src; src++, str++)
                            *str = *src;
                    }
                }
                charsNeeded += sepLen;
                if (str && *pcbFormat >= charsNeeded * sizeof(WCHAR))
                {
                    strcpyW(str, sep);
                    str += sepLen;
                }
                if (dwFormatStrType & CRYPT_FORMAT_STR_MULTI_LINE)
                {
                    charsNeeded += 2 * strlenW(indent);
                    if (str && *pcbFormat >= charsNeeded * sizeof(WCHAR))
                    {
                        strcpyW(str, indent);
                        str += strlenW(indent);
                        strcpyW(str, indent);
                        str += strlenW(indent);
                    }
                }
                charsNeeded += qualifierLen;
                if (str && *pcbFormat >= charsNeeded * sizeof(WCHAR))
                {
                    memcpy(str, qualifier, qualifierLen * sizeof(WCHAR));
                    str += qualifierLen;
                }
                charsNeeded += headingSepLen;
                if (str && *pcbFormat >= charsNeeded * sizeof(WCHAR))
                {
                    strcpyW(str, headingSep);
                    str += headingSepLen;
                }
                /* This if block is deliberately redundant with the same if
                 * block above, in order to keep the code more readable (the
                 * code flow follows the order in which the strings are output.)
                 */
                if (!strcmp(qualifierInfo->pszPolicyQualifierId,
                 szOID_PKIX_POLICY_QUALIFIER_CPS))
                {
                    if (!str || *pcbFormat < charsNeeded * sizeof(WCHAR))
                    {
                        /* Insufficient space, determine how much is needed. */
                        ret = CRYPT_FormatCPS(dwCertEncodingType,
                         dwFormatStrType, qualifierInfo->Qualifier.pbData,
                         qualifierInfo->Qualifier.cbData, NULL, &size);
                        if (ret)
                            charsNeeded += size - 1;
                    }
                    else
                    {
                        sizeRemaining = *pcbFormat / sizeof(WCHAR);
                        sizeRemaining -= str - (LPWSTR)pbFormat;
                        ret = CRYPT_FormatCPS(dwCertEncodingType,
                         dwFormatStrType, qualifierInfo->Qualifier.pbData,
                         qualifierInfo->Qualifier.cbData, str, &sizeRemaining);
                        if (ret || GetLastError() == ERROR_MORE_DATA)
                        {
                            charsNeeded += sizeRemaining - 1;
                            str += sizeRemaining - 1;
                        }
                    }
                }
                else if (!strcmp(qualifierInfo->pszPolicyQualifierId,
                 szOID_PKIX_POLICY_QUALIFIER_USERNOTICE))
                {
                    if (!str || *pcbFormat < charsNeeded * sizeof(WCHAR))
                    {
                        /* Insufficient space, determine how much is needed. */
                        ret = CRYPT_FormatUserNotice(dwCertEncodingType,
                         dwFormatStrType, qualifierInfo->Qualifier.pbData,
                         qualifierInfo->Qualifier.cbData, NULL, &size);
                        if (ret)
                            charsNeeded += size - 1;
                    }
                    else
                    {
                        sizeRemaining = *pcbFormat / sizeof(WCHAR);
                        sizeRemaining -= str - (LPWSTR)pbFormat;
                        ret = CRYPT_FormatUserNotice(dwCertEncodingType,
                         dwFormatStrType, qualifierInfo->Qualifier.pbData,
                         qualifierInfo->Qualifier.cbData, str, &sizeRemaining);
                        if (ret || GetLastError() == ERROR_MORE_DATA)
                        {
                            charsNeeded += sizeRemaining - 1;
                            str += sizeRemaining - 1;
                        }
                    }
                }
                else
                {
                    if (!str || *pcbFormat < charsNeeded * sizeof(WCHAR))
                    {
                        /* Insufficient space, determine how much is needed. */
                        ret = CRYPT_FormatHexString(
                         qualifierInfo->Qualifier.pbData,
                         qualifierInfo->Qualifier.cbData, NULL, &size);
                        if (ret)
                            charsNeeded += size - 1;
                    }
                    else
                    {
                        sizeRemaining = *pcbFormat / sizeof(WCHAR);
                        sizeRemaining -= str - (LPWSTR)pbFormat;
                        ret = CRYPT_FormatHexString(
                         qualifierInfo->Qualifier.pbData,
                         qualifierInfo->Qualifier.cbData, str, &sizeRemaining);
                        if (ret || GetLastError() == ERROR_MORE_DATA)
                        {
                            charsNeeded += sizeRemaining - 1;
                            str += sizeRemaining - 1;
                        }
                    }
                }
            }
        }
        LocalFree(policies);
        if (ret)
        {
            if (!pbFormat)
                *pcbFormat = charsNeeded * sizeof(WCHAR);
            else if (*pcbFormat < charsNeeded * sizeof(WCHAR))
            {
                *pcbFormat = charsNeeded * sizeof(WCHAR);
                SetLastError(ERROR_MORE_DATA);
                ret = FALSE;
            }
            else
                *pcbFormat = charsNeeded * sizeof(WCHAR);
        }
    }
    return ret;
}
Esempio n. 26
0
PCCTL_CONTEXT WINAPI CertCreateCTLContext(DWORD dwMsgAndCertEncodingType,
 const BYTE *pbCtlEncoded, DWORD cbCtlEncoded)
{
    PCTL_CONTEXT ctl = NULL;
    HCRYPTMSG msg;
    BOOL ret;
    BYTE *content = NULL;
    DWORD contentSize = 0, size;
    PCTL_INFO ctlInfo = NULL;

    TRACE("(%08x, %p, %d)\n", dwMsgAndCertEncodingType, pbCtlEncoded,
     cbCtlEncoded);

    if (GET_CERT_ENCODING_TYPE(dwMsgAndCertEncodingType) != X509_ASN_ENCODING)
    {
        SetLastError(E_INVALIDARG);
        return NULL;
    }
    if (!pbCtlEncoded || !cbCtlEncoded)
    {
        SetLastError(ERROR_INVALID_DATA);
        return NULL;
    }
    msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING | X509_ASN_ENCODING, 0, 0,
     0, NULL, NULL);
    if (!msg)
        return NULL;
    ret = CryptMsgUpdate(msg, pbCtlEncoded, cbCtlEncoded, TRUE);
    if (!ret)
    {
        SetLastError(ERROR_INVALID_DATA);
        goto end;
    }
    /* Check that it's really a CTL */
    ret = CryptMsgGetParam(msg, CMSG_INNER_CONTENT_TYPE_PARAM, 0, NULL, &size);
    if (ret)
    {
        char *innerContent = CryptMemAlloc(size);

        if (innerContent)
        {
            ret = CryptMsgGetParam(msg, CMSG_INNER_CONTENT_TYPE_PARAM, 0,
             innerContent, &size);
            if (ret)
            {
                if (strcmp(innerContent, szOID_CTL))
                {
                    SetLastError(ERROR_INVALID_DATA);
                    ret = FALSE;
                }
            }
            CryptMemFree(innerContent);
        }
        else
        {
            SetLastError(ERROR_OUTOFMEMORY);
            ret = FALSE;
        }
    }
    if (!ret)
        goto end;
    ret = CryptMsgGetParam(msg, CMSG_CONTENT_PARAM, 0, NULL, &contentSize);
    if (!ret)
        goto end;
    content = CryptMemAlloc(contentSize);
    if (content)
    {
        ret = CryptMsgGetParam(msg, CMSG_CONTENT_PARAM, 0, content,
         &contentSize);
        if (ret)
        {
            ret = CryptDecodeObjectEx(dwMsgAndCertEncodingType, PKCS_CTL,
             content, contentSize, CRYPT_DECODE_ALLOC_FLAG, NULL,
             &ctlInfo, &size);
            if (ret)
            {
                ctl = Context_CreateDataContext(sizeof(CTL_CONTEXT));
                if (ctl)
                {
                    BYTE *data = CryptMemAlloc(cbCtlEncoded);

                    if (data)
                    {
                        memcpy(data, pbCtlEncoded, cbCtlEncoded);
                        ctl->dwMsgAndCertEncodingType =
                         X509_ASN_ENCODING | PKCS_7_ASN_ENCODING;
                        ctl->pbCtlEncoded             = data;
                        ctl->cbCtlEncoded             = cbCtlEncoded;
                        ctl->pCtlInfo                 = ctlInfo;
                        ctl->hCertStore               = NULL;
                        ctl->hCryptMsg                = msg;
                        ctl->pbCtlContext             = content;
                        ctl->cbCtlContext             = contentSize;
                    }
                    else
                    {
                        SetLastError(ERROR_OUTOFMEMORY);
                        ret = FALSE;
                    }
                }
                else
                {
                    SetLastError(ERROR_OUTOFMEMORY);
                    ret = FALSE;
                }
            }
        }
    }
    else
    {
        SetLastError(ERROR_OUTOFMEMORY);
        ret = FALSE;
    }

end:
    if (!ret)
    {
        CryptMemFree(ctl);
        ctl = NULL;
        LocalFree(ctlInfo);
        CryptMemFree(content);
        CryptMsgClose(msg);
    }
    return ctl;
}