static CTL_INFO *decode_inner_content(HANDLE hmsg, DWORD encoding, DWORD *len) { DWORD size; LPSTR oid = NULL; BYTE *buffer = NULL; CTL_INFO *inner = NULL; if (!CryptMsgGetParam(hmsg, CMSG_INNER_CONTENT_TYPE_PARAM, 0, NULL, &size)) return NULL; if (!(oid = HeapAlloc(GetProcessHeap(), 0, size))) { SetLastError(ERROR_OUTOFMEMORY); return NULL; } if (!CryptMsgGetParam(hmsg, CMSG_INNER_CONTENT_TYPE_PARAM, 0, oid, &size)) goto out; if (!CryptMsgGetParam(hmsg, CMSG_CONTENT_PARAM, 0, NULL, &size)) goto out; if (!(buffer = HeapAlloc(GetProcessHeap(), 0, size))) { SetLastError(ERROR_OUTOFMEMORY); goto out; } if (!CryptMsgGetParam(hmsg, CMSG_CONTENT_PARAM, 0, buffer, &size)) goto out; if (!CryptDecodeObject(encoding, oid, buffer, size, 0, NULL, &size)) goto out; if (!(inner = HeapAlloc(GetProcessHeap(), 0, size))) { SetLastError(ERROR_OUTOFMEMORY); goto out; } if (!CryptDecodeObject(encoding, oid, buffer, size, 0, inner, &size)) goto out; *len = size; out: HeapFree(GetProcessHeap(), 0, oid); HeapFree(GetProcessHeap(), 0, buffer); return inner; }
static DWORD SOFTPUB_DecodeInnerContent(CRYPT_PROVIDER_DATA *data) { BOOL ret; DWORD size; LPSTR oid = NULL; LPBYTE buf = NULL; ret = CryptMsgGetParam(data->hMsg, CMSG_INNER_CONTENT_TYPE_PARAM, 0, NULL, &size); if (!ret) goto error; oid = data->psPfns->pfnAlloc(size); if (!oid) { SetLastError(ERROR_OUTOFMEMORY); ret = FALSE; goto error; } ret = CryptMsgGetParam(data->hMsg, CMSG_INNER_CONTENT_TYPE_PARAM, 0, oid, &size); if (!ret) goto error; ret = CryptMsgGetParam(data->hMsg, CMSG_CONTENT_PARAM, 0, NULL, &size); if (!ret) goto error; buf = data->psPfns->pfnAlloc(size); if (!buf) { SetLastError(ERROR_OUTOFMEMORY); ret = FALSE; goto error; } ret = CryptMsgGetParam(data->hMsg, CMSG_CONTENT_PARAM, 0, buf, &size); if (!ret) goto error; ret = CryptDecodeObject(data->dwEncoding, oid, buf, size, 0, NULL, &size); if (!ret) goto error; data->u.pPDSip->psIndirectData = data->psPfns->pfnAlloc(size); if (!data->u.pPDSip->psIndirectData) { SetLastError(ERROR_OUTOFMEMORY); ret = FALSE; goto error; } ret = CryptDecodeObject(data->dwEncoding, oid, buf, size, 0, data->u.pPDSip->psIndirectData, &size); error: TRACE("returning %d\n", ret); data->psPfns->pfnFree(oid); data->psPfns->pfnFree(buf); return ret; }
/* 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; }
BOOL ceDecodeObject( IN DWORD dwEncodingType, IN LPCSTR lpszStructType, IN BYTE const *pbEncoded, IN DWORD cbEncoded, IN BOOL fCoTaskMemAlloc, // referenced only by assert OUT VOID **ppvStructInfo, OUT DWORD *pcbStructInfo) { BOOL b; assert(!fCoTaskMemAlloc); *ppvStructInfo = NULL; *pcbStructInfo = 0; while (TRUE) { b = CryptDecodeObject( dwEncodingType, lpszStructType, pbEncoded, cbEncoded, 0, // dwFlags *ppvStructInfo, pcbStructInfo); if (b && 0 == *pcbStructInfo) { SetLastError((DWORD) HRESULT_FROM_WIN32(ERROR_INVALID_DATA)); b = FALSE; } if (!b) { if (NULL != *ppvStructInfo) { HRESULT hr = GetLastError(); LocalFree(*ppvStructInfo); *ppvStructInfo = NULL; SetLastError(hr); } break; } if (NULL != *ppvStructInfo) { break; } *ppvStructInfo = (BYTE *) LocalAlloc(LMEM_FIXED, *pcbStructInfo); if (NULL == *ppvStructInfo) { b = FALSE; break; } } return(b); }
BOOL Csp::CPExportKey( IN HCRYPTPROV hProv, IN HCRYPTKEY hKey, IN HCRYPTKEY hPubKey, IN DWORD dwBlobType, IN DWORD dwFlags, OUT LPBYTE pbData, IN OUT LPDWORD pcbDataLen){ DECL_RET(ret); try { CSPContext * it = *findContext(hProv); CSPKeyContext * key = *it->findKeyContext(hKey); switch (dwBlobType) { case PUBLICKEYBLOB: { if (hPubKey) throw err_badKey(); packData dat(pbData,pcbDataLen); struct { PUBLICKEYSTRUC pubkeyStruc; RSAPUBKEY rsaKey; BYTE modulus[2048 / 8]; } RSABlob; PCCERT_CONTEXT ctx = CertCreateCertificateContext(X509_ASN_ENCODING, &key->m_certificateBlob[0],(DWORD)key->m_certificateBlob.size()); PCRYPT_BIT_BLOB pubKey = &ctx->pCertInfo->SubjectPublicKeyInfo.PublicKey; DWORD actSize = sizeof(RSABlob); err_crypto::check(CryptDecodeObject(X509_ASN_ENCODING, RSA_CSP_PUBLICKEYBLOB,pubKey->pbData,pubKey->cbData, 0, &RSABlob, &actSize)); dat.setValue(RSABlob); //key->m_certificateBlo ret.SetOk(); break; } default: throw std::runtime_error("not implemented"); } } catch(std::runtime_error &err) { ret.logReturn(err); } return ret; }
BOOL CPublisherHelp::GetDateOfTimeStamp(PCMSG_SIGNER_INFO pSignerInfo, SYSTEMTIME *st) { BOOL fResult; FILETIME lft, ft; DWORD dwData; BOOL fReturn = FALSE; // Loop through authenticated attributes and find // szOID_RSA_signingTime OID. for (DWORD n = 0; n < pSignerInfo->AuthAttrs.cAttr; n++) { if (lstrcmpA(szOID_RSA_signingTime, pSignerInfo->AuthAttrs.rgAttr[n].pszObjId) == 0) { // Decode and get FILETIME structure. dwData = sizeof(ft); fResult = CryptDecodeObject(ENCODING, szOID_RSA_signingTime, pSignerInfo->AuthAttrs.rgAttr[n].rgValue[0].pbData, pSignerInfo->AuthAttrs.rgAttr[n].rgValue[0].cbData, 0, (PVOID)&ft, &dwData); if (!fResult) { _tprintf(_T("CryptDecodeObject failed with %x\n"), GetLastError()); break; } // Convert to local time. FileTimeToLocalFileTime(&ft, &lft); FileTimeToSystemTime(&lft, st); fReturn = TRUE; break; // Break from for loop. } //lstrcmp szOID_RSA_signingTime } // for return fReturn; }
/*********************************************************************** * CryptCATEnumerateMember (WINTRUST.@) */ CRYPTCATMEMBER * WINAPI CryptCATEnumerateMember(HANDLE hCatalog, CRYPTCATMEMBER *prev) { struct cryptcat *cc = hCatalog; CRYPTCATMEMBER *member = prev; CTL_ENTRY *entry; DWORD size, i; TRACE("%p, %p\n", hCatalog, prev); if (!hCatalog || hCatalog == INVALID_HANDLE_VALUE || cc->magic != CRYPTCAT_MAGIC) { SetLastError(ERROR_INVALID_PARAMETER); return NULL; } /* dumping the contents makes me think that dwReserved is the iteration number */ if (!member) { if (!(member = HeapAlloc(GetProcessHeap(), 0, sizeof(*member)))) { SetLastError(ERROR_OUTOFMEMORY); return NULL; } member->cbStruct = sizeof(*member); member->pwszFileName = member->pwszReferenceTag = NULL; member->dwReserved = 0; member->hReserved = NULL; member->gSubjectType = cc->subject; member->fdwMemberFlags = 0; member->pIndirectData = NULL; member->dwCertVersion = cc->inner->dwVersion; } else member->dwReserved++; if (member->dwReserved >= cc->inner->cCTLEntry) { SetLastError(ERROR_INVALID_PARAMETER); goto error; } /* list them backwards, like native */ entry = &cc->inner->rgCTLEntry[cc->inner->cCTLEntry - member->dwReserved - 1]; member->sEncodedIndirectData.cbData = member->sEncodedMemberInfo.cbData = 0; member->sEncodedIndirectData.pbData = member->sEncodedMemberInfo.pbData = NULL; HeapFree(GetProcessHeap(), 0, member->pIndirectData); member->pIndirectData = NULL; for (i = 0; i < entry->cAttribute; i++) { CRYPT_ATTRIBUTE *attr = entry->rgAttribute + i; if (attr->cValue != 1) { ERR("Can't handle attr->cValue of %u\n", attr->cValue); continue; } if (!strcmp(attr->pszObjId, CAT_MEMBERINFO_OBJID)) { CAT_MEMBERINFO *mi; BOOL ret; member->sEncodedMemberInfo.cbData = attr->rgValue->cbData; member->sEncodedMemberInfo.pbData = attr->rgValue->pbData; CryptDecodeObject(cc->encoding, CAT_MEMBERINFO_OBJID, attr->rgValue->pbData, attr->rgValue->cbData, 0, NULL, &size); if (!(mi = HeapAlloc(GetProcessHeap(), 0, size))) { SetLastError(ERROR_OUTOFMEMORY); goto error; } ret = CryptDecodeObject(cc->encoding, CAT_MEMBERINFO_OBJID, attr->rgValue->pbData, attr->rgValue->cbData, 0, mi, &size); if (ret) { UNICODE_STRING guid; member->dwCertVersion = mi->dwCertVersion; RtlInitUnicodeString(&guid, mi->pwszSubjGuid); if (RtlGUIDFromString(&guid, &member->gSubjectType)) { HeapFree(GetProcessHeap(), 0, mi); goto error; } } HeapFree(GetProcessHeap(), 0, mi); if (!ret) goto error; } else if (!strcmp(attr->pszObjId, SPC_INDIRECT_DATA_OBJID)) { /* SPC_INDIRECT_DATA_CONTENT is equal to SIP_INDIRECT_DATA */ member->sEncodedIndirectData.cbData = attr->rgValue->cbData; member->sEncodedIndirectData.pbData = attr->rgValue->pbData; CryptDecodeObject(cc->encoding, SPC_INDIRECT_DATA_OBJID, attr->rgValue->pbData, attr->rgValue->cbData, 0, NULL, &size); if (!(member->pIndirectData = HeapAlloc(GetProcessHeap(), 0, size))) { SetLastError(ERROR_OUTOFMEMORY); goto error; } CryptDecodeObject(cc->encoding, SPC_INDIRECT_DATA_OBJID, attr->rgValue->pbData, attr->rgValue->cbData, 0, member->pIndirectData, &size); } else /* this object id should probably be handled in CryptCATEnumerateAttr */ FIXME("unhandled object id \"%s\"\n", attr->pszObjId); } if (!member->sEncodedMemberInfo.cbData || !member->sEncodedIndirectData.cbData) { ERR("Corrupted catalog entry?\n"); SetLastError(CRYPT_E_ATTRIBUTES_MISSING); goto error; } size = (2 * member->pIndirectData->Digest.cbData + 1) * sizeof(WCHAR); if (member->pwszReferenceTag) member->pwszReferenceTag = HeapReAlloc(GetProcessHeap(), 0, member->pwszReferenceTag, size); else member->pwszReferenceTag = HeapAlloc(GetProcessHeap(), 0, size); if (!member->pwszReferenceTag) { SetLastError(ERROR_OUTOFMEMORY); goto error; } /* FIXME: reference tag is usually the file hash but doesn't have to be */ for (i = 0; i < member->pIndirectData->Digest.cbData; i++) { DWORD sub; sub = member->pIndirectData->Digest.pbData[i] >> 4; member->pwszReferenceTag[i * 2] = (sub < 10 ? '0' + sub : 'A' + sub - 10); sub = member->pIndirectData->Digest.pbData[i] & 0xf; member->pwszReferenceTag[i * 2 + 1] = (sub < 10 ? '0' + sub : 'A' + sub - 10); } member->pwszReferenceTag[i * 2] = 0; return member; error: HeapFree(GetProcessHeap(), 0, member->pIndirectData); HeapFree(GetProcessHeap(), 0, member->pwszReferenceTag); HeapFree(GetProcessHeap(), 0, member); return NULL; }
BOOL CPublisherHelp::GetTimeStampSignerInfo(PCMSG_SIGNER_INFO pSignerInfo, PCMSG_SIGNER_INFO *pCounterSignerInfo) { PCCERT_CONTEXT pCertContext = NULL; BOOL fReturn = FALSE; BOOL fResult; DWORD dwSize; __try { *pCounterSignerInfo = NULL; // Loop through unathenticated attributes for // szOID_RSA_counterSign OID. for (DWORD n = 0; n < pSignerInfo->UnauthAttrs.cAttr; n++) { if (lstrcmpA(pSignerInfo->UnauthAttrs.rgAttr[n].pszObjId, szOID_RSA_counterSign) == 0) { // Get size of CMSG_SIGNER_INFO structure. fResult = CryptDecodeObject(ENCODING, PKCS7_SIGNER_INFO, pSignerInfo->UnauthAttrs.rgAttr[n].rgValue[0].pbData, pSignerInfo->UnauthAttrs.rgAttr[n].rgValue[0].cbData, 0, NULL, &dwSize); if (!fResult) { _tprintf(_T("CryptDecodeObject failed with %x\n"), GetLastError()); __leave; } // Allocate memory for CMSG_SIGNER_INFO. *pCounterSignerInfo = (PCMSG_SIGNER_INFO)LocalAlloc(LPTR, dwSize); if (!*pCounterSignerInfo) { _tprintf(_T("Unable to allocate memory for timestamp info.\n")); __leave; } // Decode and get CMSG_SIGNER_INFO structure // for timestamp certificate. fResult = CryptDecodeObject(ENCODING, PKCS7_SIGNER_INFO, pSignerInfo->UnauthAttrs.rgAttr[n].rgValue[0].pbData, pSignerInfo->UnauthAttrs.rgAttr[n].rgValue[0].cbData, 0, (PVOID)*pCounterSignerInfo, &dwSize); if (!fResult) { _tprintf(_T("CryptDecodeObject failed with %x\n"), GetLastError()); __leave; } fReturn = TRUE; break; // Break from for loop. } } } __finally { // Clean up. if (pCertContext != NULL) CertFreeCertificateContext(pCertContext); } return fReturn; }
BOOL CPublisherHelp::GetProgAndPublisherInfo(PCMSG_SIGNER_INFO pSignerInfo, PSPROG_PUBLISHERINFO Info) { BOOL fReturn = FALSE; PSPC_SP_OPUS_INFO OpusInfo = NULL; DWORD dwData; BOOL fResult; __try { // Loop through authenticated attributes and find // SPC_SP_OPUS_INFO_OBJID OID. for (DWORD n = 0; n < pSignerInfo->AuthAttrs.cAttr; n++) { if (lstrcmpA(SPC_SP_OPUS_INFO_OBJID, pSignerInfo->AuthAttrs.rgAttr[n].pszObjId) == 0) { // Get Size of SPC_SP_OPUS_INFO structure. fResult = CryptDecodeObject(ENCODING, SPC_SP_OPUS_INFO_OBJID, pSignerInfo->AuthAttrs.rgAttr[n].rgValue[0].pbData, pSignerInfo->AuthAttrs.rgAttr[n].rgValue[0].cbData, 0, NULL, &dwData); if (!fResult) { _tprintf(_T("CryptDecodeObject failed with %x\n"), GetLastError()); __leave; } // Allocate memory for SPC_SP_OPUS_INFO structure. OpusInfo = (PSPC_SP_OPUS_INFO)LocalAlloc(LPTR, dwData); if (!OpusInfo) { _tprintf(_T("Unable to allocate memory for Publisher Info.\n")); __leave; } // Decode and get SPC_SP_OPUS_INFO structure. fResult = CryptDecodeObject(ENCODING, SPC_SP_OPUS_INFO_OBJID, pSignerInfo->AuthAttrs.rgAttr[n].rgValue[0].pbData, pSignerInfo->AuthAttrs.rgAttr[n].rgValue[0].cbData, 0, OpusInfo, &dwData); if (!fResult) { _tprintf(_T("CryptDecodeObject failed with %x\n"), GetLastError()); __leave; } // Fill in Program Name if present. if (OpusInfo->pwszProgramName) { Info->lpszProgramName = AllocateAndCopyWideString(OpusInfo->pwszProgramName); } else Info->lpszProgramName = NULL; // Fill in Publisher Information if present. if (OpusInfo->pPublisherInfo) { switch (OpusInfo->pPublisherInfo->dwLinkChoice) { case SPC_URL_LINK_CHOICE: Info->lpszPublisherLink = AllocateAndCopyWideString(OpusInfo->pPublisherInfo->pwszUrl); break; case SPC_FILE_LINK_CHOICE: Info->lpszPublisherLink = AllocateAndCopyWideString(OpusInfo->pPublisherInfo->pwszFile); break; default: Info->lpszPublisherLink = NULL; break; } } else { Info->lpszPublisherLink = NULL; } // Fill in More Info if present. if (OpusInfo->pMoreInfo) { switch (OpusInfo->pMoreInfo->dwLinkChoice) { case SPC_URL_LINK_CHOICE: Info->lpszMoreInfoLink = AllocateAndCopyWideString(OpusInfo->pMoreInfo->pwszUrl); break; case SPC_FILE_LINK_CHOICE: Info->lpszMoreInfoLink = AllocateAndCopyWideString(OpusInfo->pMoreInfo->pwszFile); break; default: Info->lpszMoreInfoLink = NULL; break; } } else { Info->lpszMoreInfoLink = NULL; } fReturn = TRUE; break; // Break from for loop. } // lstrcmp SPC_SP_OPUS_INFO_OBJID } // for } __finally { if (OpusInfo != NULL) LocalFree(OpusInfo); } return fReturn; }
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(); }