わざわざやることじゃない気がしますが、証明書 ( 試してみたら、.crl でもいけました ) から署名部分を取り出すサンプル。ググった限りでは見当たらない感じだったので...。
なんとなく、certutil ツールの署名部分の出力にあわせる感じにしてみました。とりあえず、コンソールに日本語を出す必要があるときは、setlocale() して _T 版を使うようにしてるんですが、CERT_SIGNED_CONTENT_INFO.SignatureAlgorithm.pszObjId って LPSTR なのか...。
興味深いのが CryptFindOIDInfo() 関数 で、CRYPT_OID_INFO 構造体のポインタを返します。が、そのポインタは別に解放する必要がない、と。デバッガで動作をのぞいてみると、どうやら CRYPT_OID_INFO 構造体がずらっと並んでいるようで ( 今回は、アルゴリズムを示す OID で確認 )。
メモリの場所的には、crypt32.dll の領域なんで、そこにずらずら並んだデータから対象となるアルゴリズムのアドレスを返してくれるようです。こんな使い方もあるんですね。
#include "stdafx.h"
#include <locale.h>
#include <windows.h>
#pragma comment (lib, "crypt32.lib")
int _tmain(int argc, _TCHAR* argv[])
{
HANDLE hFile = NULL;
BYTE* pbFile = NULL;
DWORD cbFile = 0;
BYTE* pbData = NULL;
DWORD cbData = 0;
BOOL result = FALSE;
PCERT_SIGNED_CONTENT_INFO pcsci = NULL;
PCCRYPT_OID_INFO pcoi = NULL;
::_tsetlocale(LC_ALL, _T("Japanese"));
hFile =
::CreateFile(_T("c:\\sample.cer"),
GENERIC_READ, 0, NULL, OPEN_EXISTING,
FILE_ATTRIBUTE_NORMAL, NULL);
if (hFile == INVALID_HANDLE_VALUE) {
_tprintf(_T("CreateFile failed: %0.8x\n"),
::GetLastError());
goto fin;
}
cbFile = ::GetFileSize(hFile, NULL);
if (!cbFile) {
_tprintf(_T("GetFileSize failed: %0.8x\n"),
::GetLastError());
goto fin_close_file;
}
pbFile = (BYTE *)malloc(cbFile);
result =
::ReadFile(hFile, pbFile, cbFile, &cbFile, NULL);
if (!result) {
_tprintf(_T("ReadFile failed: %0.8x\n"),
::GetLastError());
goto fin_free;
}
result =
::CryptDecodeObject(X509_ASN_ENCODING, X509_CERT,
pbFile, cbFile, 0, NULL, &cbData);
if (!result) {
_tprintf(_T("CryptDecodeObject(1) failed: %0.8x\n"),
::GetLastError());
goto fin_free;
}
pbData = (BYTE *)malloc(cbData);
result =
::CryptDecodeObject(X509_ASN_ENCODING, X509_CERT,
pbFile, cbFile, 0, pbData, &cbData);
if (!result) {
_tprintf(_T("CryptDecodeObject(2) failed: %0.8x\n"),
::GetLastError());
goto fin_free;
}
pcsci = (PCERT_SIGNED_CONTENT_INFO)pbData;
_tprintf(_T("署名アルゴリズム:\n"));
printf(" アルゴリズムのオブジェクト ID: %s ",
pcsci->SignatureAlgorithm.pszObjId);
pcoi =
::CryptFindOIDInfo(CRYPT_OID_INFO_OID_KEY,
pcsci->SignatureAlgorithm.pszObjId,
CRYPT_OID_DISABLE_SEARCH_DS_FLAG);
_tprintf(_T("%s\n"), pcoi ? pcoi->pwszName : _T(""));
_tprintf(_T(" アルゴリズムのパラメーター:\n"));
_tprintf(_T(" %0.2x %0.2x\n"),
pcsci->SignatureAlgorithm.Parameters.pbData[0],
pcsci->SignatureAlgorithm.Parameters.pbData[1]);
_tprintf(_T("署名: UnusedBits=%d\n"),
pcsci->Signature.cUnusedBits);
_tprintf(_T(" 0000 "));
for (size_t i = 0; i < pcsci->Signature.cbData; i++)
{
_tprintf(_T("%0.2x "), pcsci->Signature.pbData[i]);
if ((i + 1) % 8 == 0)
{
_tprintf(_T(" "));
}
if ((i + 1) % 16 == 0 && (i + 1) < pcsci->Signature.cbData)
{
_tprintf(_T("\n %0.4x "), i + 1);
}
}
_tprintf(_T("\n"));
free(pbData);
fin_free:
free(pbFile);
fin_close_file:
::CloseHandle(hFile);
fin:
printf("--- finish. ---\n");
getchar();
return 0;
}
またまた勉強会ということで、今回は JavaScript とアドテクの勉強会に行ってきました。場所は渋谷のヒカリエ。機材の不調とかありましたが、内容はなかなかおもしろかったです。広告を Web ページ上に出すときの JavaScript のコツ、とか、PhantomJS の紹介だとか、バンディットアルゴリズムだとか。
以前、わたしが参加してたころの勉強会って、コミュニティベースのやつだったりベンダーがやってる系のやつだったりしましたが、今回は人材紹介とかいろいろやってる会社が主催のものでした。これ、考えてみると結構ありだなぁ、と。
勉強会に参加する、ってくらいの人は、それなりに仕事に対するモチベーションがあるんでしょうし ( もちろん、会社に言われてイヤイヤ参加してる人もいるでしょうけど )、そういう人たちとのつながりができれば、そりゃいいことなわけで。
単に『勉強会』といっても、場所やら講師やらなんのかんのでコストがかかるわけですから、その辺はギブアンドテイクですね。