/* 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; }
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(); }