1 // SoftEther UT-VPN SourceCode
\r
3 // Copyright (C) 2004-2010 SoftEther Corporation.
\r
4 // Copyright (C) 2004-2010 University of Tsukuba, Japan.
\r
5 // Copyright (C) 2003-2010 Daiyuu Nobori.
\r
6 // All Rights Reserved.
\r
8 // http://utvpn.tsukuba.ac.jp/
\r
10 // This program is free software; you can redistribute it and/or
\r
11 // modify it under the terms of the GNU General Public License
\r
12 // version 2 as published by the Free Software Foundation.
\r
14 // This program is distributed in the hope that it will be useful,
\r
15 // but WITHOUT ANY WARRANTY; without even the implied warranty of
\r
16 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
\r
17 // GNU General Public License for more details.
\r
19 // You should have received a copy of the GNU General Public License version 2
\r
20 // along with this program; if not, write to the Free Software
\r
21 // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
\r
23 // このファイルは GPL バージョン 2 ライセンスで公開されています。
\r
24 // 誰でもこのファイルの内容を複製、改変したり、改変したバージョンを再配布
\r
25 // することができます。ただし、原著作物を改変した場合は、原著作物の著作権表示
\r
26 // を除去することはできません。改変した著作物を配布する場合は、改変実施者の
\r
27 // 著作権表示を原著作物の著作権表示に付随して記載するようにしてください。
\r
29 // この SoftEther UT-VPN オープンソース・プロジェクトは、日本国の
\r
30 // ソフトイーサ株式会社 (SoftEther Corporation, http://www.softether.co.jp/ )
\r
31 // および筑波大学 (University of Tsukuba, http://www.tsukuba.ac.jp/ ) によって
\r
33 // 本プログラムの配布者は、本プログラムを、業としての利用以外のため、
\r
34 // および、試験または研究のために利用が行われることを想定して配布
\r
36 // SoftEther UT-VPN プロジェクトの Web サイトは http://utvpn.tsukuba.ac.jp/ に
\r
38 // 本ソフトウェアの不具合の修正、機能改良、セキュリティホールの修復などのコード
\r
39 // の改変を行った場合で、その成果物を SoftEther UT-VPN プロジェクトに提出して
\r
40 // いただける場合は、 http://utvpn.tsukuba.ac.jp/ までソースコードを送付して
\r
41 // ください。SoftEther UT-VPN プロジェクトの本体リリースまたはブランチリリース
\r
44 // GPL に基づいて原著作物が提供される本ソフトウェアの改良版を配布、販売する
\r
45 // 場合は、そのソースコードを GPL に基づいて誰にでも開示する義務が生じます。
\r
47 // 本ソフトウェアに関連する著作権、特許権、商標権はソフトイーサ株式会社
\r
48 // (SoftEther Corporation) およびその他の著作権保持者が保有しています。
\r
49 // ソフトイーサ株式会社等はこれらの権利を放棄していません。本ソフトウェアの
\r
50 // 二次著作物を配布、販売する場合は、これらの権利を侵害しないようにご注意
\r
53 // お願い: どのような通信ソフトウェアにも通常は必ず未発見の
\r
54 // セキュリティホールが潜んでいます。本ソースコードをご覧いただいた結果、
\r
55 // UT-VPN にセキュリティホールを発見された場合は、当該セキュリティホールの
\r
56 // 情報を不特定多数に開示される前に、必ず、ソフトイーサ株式会社
\r
57 // および脆弱性情報の届出を受け付ける公的機関まで通報いただき、
\r
58 // 公益保護にご協力いただきますようお願い申し上げます。
\r
60 // ソフトイーサ株式会社は、当該セキュリティホールについて迅速に対処を
\r
61 // 行い、UT-VPN および UT-VPN に関連するソフトウェアのユーザー・顧客
\r
64 // ソフトイーサへの届出先: http://www.softether.co.jp/jp/contact/
\r
65 // 日本国内の脆弱性情報届出受付公的機関:
\r
67 // http://www.ipa.go.jp/security/vuln/report/
\r
69 // 上記各事項について不明な点は、ソフトイーサ株式会社までご連絡ください。
\r
70 // 連絡先: http://www.softether.co.jp/jp/contact/
\r
72 // -----------------------------------------------
\r
75 // 新規リリース by SoftEther
\r
76 // -----------------------------------------------
\r
79 // セキュリティトークン管理モジュール
\r
85 #include <windows.h>
\r
95 #include <openssl/ssl.h>
\r
96 #include <openssl/err.h>
\r
97 #include <openssl/rand.h>
\r
98 #include <openssl/engine.h>
\r
99 #include <openssl/bio.h>
\r
100 #include <openssl/x509.h>
\r
101 #include <openssl/pkcs7.h>
\r
102 #include <openssl/pkcs12.h>
\r
103 #include <openssl/rc4.h>
\r
104 #include <openssl/md5.h>
\r
105 #include <openssl/sha.h>
\r
106 #include <Mayaqua/Mayaqua.h>
\r
107 #include <Mayaqua/cryptoki.h>
\r
110 #define MAX_OBJ 1024 // ハードウェア内の最大オブジェクト数 (想定)
\r
112 #define A_SIZE(a, i) (a[(i)].ulValueLen)
\r
113 #define A_SET(a, i, value, size) (a[i].pValue = value;a[i].ulValueLen = size;)
\r
118 // Win32 用 DLL 読み込み
\r
119 HINSTANCE Win32SecureLoadLibraryEx(char *dllname, DWORD flags)
\r
121 char tmp1[MAX_PATH];
\r
122 char tmp2[MAX_PATH];
\r
123 char tmp3[MAX_PATH];
\r
126 if (dllname == NULL)
\r
131 Format(tmp1, sizeof(tmp1), "%s\\%s", MsGetSystem32Dir(), dllname);
\r
132 Format(tmp2, sizeof(tmp2), "%s\\JPKI\\%s", MsGetProgramFilesDir(), dllname);
\r
133 Format(tmp3, sizeof(tmp3), "%s\\LGWAN\\%s", MsGetProgramFilesDir(), dllname);
\r
135 h = LoadLibraryEx(dllname, NULL, flags);
\r
141 h = LoadLibraryEx(tmp1, NULL, flags);
\r
147 h = LoadLibraryEx(tmp2, NULL, flags);
\r
153 h = LoadLibraryEx(tmp3, NULL, flags);
\r
162 // 指定したデバイスがインストールされているか調査
\r
163 bool Win32IsDeviceSupported(SECURE_DEVICE *dev)
\r
172 // DLL が読み込み可能かチェック
\r
173 hInst = Win32SecureLoadLibraryEx(dev->ModuleName, DONT_RESOLVE_DLL_REFERENCES);
\r
179 FreeLibrary(hInst);
\r
185 bool Win32LoadSecModule(SECURE *sec)
\r
189 CK_FUNCTION_LIST_PTR api = NULL;
\r
190 CK_RV (*get_function_list)(CK_FUNCTION_LIST_PTR_PTR);
\r
197 if (sec->Dev->Id == 9)
\r
199 char username[MAX_SIZE];
\r
201 // 住基ネットのデバイスドライバでは、Software\JPKI レジストリキーの内容を
\r
202 // SYSTEM の HKLU でも持っていなければならないので、もし持っていない場合は
\r
204 // if (MsRegIsValue(REG_CURRENT_USER, "Software\\JPKI", "Name") == false ||
\r
205 // MsRegIsValue(REG_CURRENT_USER, "Software\\JPKI", "RWType") == false)
\r
206 size = sizeof(username);
\r
207 GetUserName(username, &size);
\r
208 if (StrCmpi(username, "System") == 0)
\r
210 TOKEN_LIST *t = MsRegEnumKey(REG_USERS, NULL);
\r
216 for (i = 0;i < t->NumTokens;i++)
\r
218 char tmp[MAX_PATH];
\r
220 if (StrCmpi(t->Token[i], ".DEFAULT") != 0 && StrCmpi(t->Token[i], "S-1-5-18") != 0)
\r
222 Format(tmp, sizeof(tmp), "%s\\Software\\JPKI", t->Token[i]);
\r
224 if (MsRegIsValue(REG_USERS, tmp, "Name") && MsRegIsValue(REG_USERS, tmp, "RWType"))
\r
226 char *name = MsRegReadStr(REG_USERS, tmp, "Name");
\r
227 char *port = MsRegReadStr(REG_USERS, tmp, "Port");
\r
228 UINT type = MsRegReadInt(REG_USERS, tmp, "RWType");
\r
230 MsRegWriteStr(REG_CURRENT_USER, "Software\\JPKI", "Name", name);
\r
231 MsRegWriteStr(REG_CURRENT_USER, "Software\\JPKI", "Port", port);
\r
232 MsRegWriteInt(REG_CURRENT_USER, "Software\\JPKI", "RWType", type);
\r
247 hInst = Win32SecureLoadLibraryEx(sec->Dev->ModuleName, 0);
\r
255 get_function_list = (CK_RV (*)(CK_FUNCTION_LIST_PTR_PTR))
\r
256 GetProcAddress(hInst, "C_GetFunctionList");
\r
258 if (get_function_list == NULL)
\r
261 FreeLibrary(hInst);
\r
265 get_function_list(&api);
\r
269 FreeLibrary(hInst);
\r
273 sec->Data = ZeroMalloc(sizeof(SEC_DATA_WIN32));
\r
283 void Win32FreeSecModule(SECURE *sec)
\r
290 if (sec->Data == NULL)
\r
296 FreeLibrary(sec->Data->hInst);
\r
305 // 指定されたデバイスが JPKI かどうか
\r
306 bool IsJPKI(bool id)
\r
308 if (id == 9 || id == 13)
\r
316 // セキュアデバイスの秘密鍵を名前を指定して署名
\r
317 bool SignSec(SECURE *sec, char *name, void *dst, void *src, UINT size)
\r
326 if (name == NULL || dst == NULL || src == NULL)
\r
328 sec->Error = SEC_ERROR_BAD_PARAMETER;
\r
332 obj = FindSecObject(sec, name, SEC_K);
\r
338 ret = SignSecByObject(sec, obj, dst, src, size);
\r
340 FreeSecObject(obj);
\r
346 bool SignSecByObject(SECURE *sec, SEC_OBJ *obj, void *dst, void *src, UINT size)
\r
348 CK_MECHANISM mechanism = {CKM_RSA_PKCS, NULL, 0};
\r
350 UCHAR hash[SIGN_HASH_SIZE];
\r
356 if (obj == NULL || dst == NULL || src == NULL)
\r
358 sec->Error = SEC_ERROR_BAD_PARAMETER;
\r
361 if (sec->SessionCreated == false)
\r
363 sec->Error = SEC_ERROR_NO_SESSION;
\r
366 if (sec->LoginFlag == false && obj->Private)
\r
368 sec->Error = SEC_ERROR_NOT_LOGIN;
\r
371 if (obj->Type != SEC_K)
\r
373 sec->Error = SEC_ERROR_BAD_PARAMETER;
\r
378 HashForSign(hash, sizeof(hash), src, size);
\r
381 ret = sec->Api->C_SignInit(sec->SessionId, &mechanism, obj->Object);
\r
385 sec->Error = SEC_ERROR_HARDWARE_ERROR;
\r
386 Debug("C_SignInit Error: 0x%x\n", ret);
\r
392 ret = sec->Api->C_Sign(sec->SessionId, hash, sizeof(hash), dst, &size);
\r
393 if (ret != CKR_OK || size != 128)
\r
396 sec->Error = SEC_ERROR_HARDWARE_ERROR;
\r
397 Debug("C_Sign Error: 0x%x\n", ret);
\r
405 bool ChangePin(SECURE *sec, char *old_pin, char *new_pin)
\r
408 if (sec == NULL || old_pin == NULL || new_pin == NULL)
\r
412 if (sec->SessionCreated == false)
\r
414 sec->Error = SEC_ERROR_NO_SESSION;
\r
417 if (sec->LoginFlag == false)
\r
419 sec->Error = SEC_ERROR_NOT_LOGIN;
\r
422 if (sec->IsReadOnly)
\r
424 sec->Error = SEC_ERROR_OPEN_SESSION;
\r
429 if (sec->Api->C_SetPIN(sec->SessionId, old_pin, StrLen(old_pin),
\r
430 new_pin, StrLen(new_pin)) != CKR_OK)
\r
439 bool WriteSecKey(SECURE *sec, bool private_obj, char *name, K *k)
\r
441 UINT key_type = CKK_RSA;
\r
442 CK_BBOOL b_true = true, b_false = false, b_private_obj = private_obj;
\r
443 UINT obj_class = CKO_PRIVATE_KEY;
\r
448 UCHAR modules[MAX_SIZE], pub[MAX_SIZE], pri[MAX_SIZE], prime1[MAX_SIZE], prime2[MAX_SIZE];
\r
451 {CKA_MODULUS, modules, 0}, // 0
\r
452 {CKA_PUBLIC_EXPONENT, pub, 0}, // 1
\r
453 {CKA_PRIVATE_EXPONENT, pri, 0}, // 2
\r
454 {CKA_PRIME_1, prime1, 0}, // 3
\r
455 {CKA_PRIME_2, prime2, 0}, // 4
\r
456 {CKA_CLASS, &obj_class, sizeof(obj_class)},
\r
457 {CKA_TOKEN, &b_true, sizeof(b_true)},
\r
458 {CKA_PRIVATE, &b_private_obj, sizeof(b_private_obj)},
\r
459 {CKA_LABEL, name, StrLen(name)},
\r
460 {CKA_KEY_TYPE, &key_type, sizeof(key_type)},
\r
461 {CKA_DERIVE, &b_false, sizeof(b_false)},
\r
462 {CKA_SUBJECT, name, StrLen(name)},
\r
463 {CKA_SENSITIVE, &b_true, sizeof(b_true)},
\r
464 {CKA_DECRYPT, &b_true, sizeof(b_true)},
\r
465 {CKA_SIGN, &b_true, sizeof(b_true)},
\r
466 {CKA_SIGN_RECOVER, &b_false, sizeof(b_false)},
\r
467 {CKA_EXTRACTABLE, &b_false, sizeof(b_false)},
\r
468 {CKA_MODIFIABLE, &b_false, sizeof(b_false)},
\r
475 if (name == NULL || k == NULL || k->private_key == false)
\r
477 sec->Error = SEC_ERROR_BAD_PARAMETER;
\r
480 if (sec->SessionCreated == false)
\r
482 sec->Error = SEC_ERROR_NO_SESSION;
\r
485 if (sec->LoginFlag == false && private_obj)
\r
487 sec->Error = SEC_ERROR_NOT_LOGIN;
\r
492 rsa = k->pkey->pkey.rsa;
\r
495 sec->Error = SEC_ERROR_BAD_PARAMETER;
\r
498 b = BigNumToBuf(rsa->n);
\r
499 ReadBuf(b, modules, sizeof(modules));
\r
500 A_SIZE(a, 0) = b->Size;
\r
503 b = BigNumToBuf(rsa->e);
\r
504 ReadBuf(b, pub, sizeof(pub));
\r
505 A_SIZE(a, 1) = b->Size;
\r
508 b = BigNumToBuf(rsa->d);
\r
509 ReadBuf(b, pri, sizeof(pri));
\r
510 A_SIZE(a, 2) = b->Size;
\r
513 b = BigNumToBuf(rsa->p);
\r
514 ReadBuf(b, prime1, sizeof(prime1));
\r
515 A_SIZE(a, 3) = b->Size;
\r
518 b = BigNumToBuf(rsa->q);
\r
519 ReadBuf(b, prime2, sizeof(prime2));
\r
520 A_SIZE(a, 4) = b->Size;
\r
524 if (CheckSecObject(sec, name, SEC_K))
\r
526 DeleteSecKey(sec, name);
\r
530 if ((ret = sec->Api->C_CreateObject(sec->SessionId, a, sizeof(a) / sizeof(a[0]), &object)) != CKR_OK)
\r
533 sec->Error = SEC_ERROR_HARDWARE_ERROR;
\r
534 Debug("ret: 0x%x\n", ret);
\r
539 EraseEnumSecObjectCache(sec);
\r
544 // 証明書オブジェクトを名前を指定して読み込み
\r
545 X *ReadSecCert(SECURE *sec, char *name)
\r
554 if (sec->SessionCreated == false)
\r
556 sec->Error = SEC_ERROR_NO_SESSION;
\r
561 obj = FindSecObject(sec, name, SEC_X);
\r
568 x = ReadSecCertFromObject(sec, obj);
\r
570 FreeSecObject(obj);
\r
576 X *ReadSecCertFromObject(SECURE *sec, SEC_OBJ *obj)
\r
582 CK_ATTRIBUTE get[] =
\r
584 {CKA_VALUE, value, sizeof(value)},
\r
591 if (sec->SessionCreated == false)
\r
593 sec->Error = SEC_ERROR_NO_SESSION;
\r
596 if (sec->LoginFlag == false && obj->Private)
\r
598 sec->Error = SEC_ERROR_NOT_LOGIN;
\r
601 if (obj->Type != SEC_X)
\r
603 sec->Error = SEC_ERROR_BAD_PARAMETER;
\r
608 if (sec->Api->C_GetAttributeValue(
\r
609 sec->SessionId, obj->Object, get, sizeof(get) / sizeof(get[0])) != CKR_OK)
\r
611 sec->Error = SEC_ERROR_HARDWARE_ERROR;
\r
615 size = A_SIZE(get, 0);
\r
619 WriteBuf(b, value, size);
\r
622 x = BufToX(b, false);
\r
625 sec->Error = SEC_ERROR_INVALID_CERT;
\r
634 bool WriteSecCert(SECURE *sec, bool private_obj, char *name, X *x)
\r
636 UINT obj_class = CKO_CERTIFICATE;
\r
637 CK_BBOOL b_true = true, b_false = false, b_private_obj = private_obj;
\r
638 UINT cert_type = CKC_X_509;
\r
639 CK_DATE start_date, end_date;
\r
640 UCHAR subject[MAX_SIZE];
\r
641 UCHAR issuer[MAX_SIZE];
\r
642 wchar_t w_subject[MAX_SIZE];
\r
643 wchar_t w_issuer[MAX_SIZE];
\r
644 UCHAR serial_number[MAX_SIZE];
\r
651 {CKA_SUBJECT, subject, 0}, // 0
\r
652 {CKA_ISSUER, issuer, 0}, // 1
\r
653 {CKA_SERIAL_NUMBER, serial_number, 0}, // 2
\r
654 {CKA_VALUE, value, 0}, // 3
\r
655 {CKA_CLASS, &obj_class, sizeof(obj_class)},
\r
656 {CKA_TOKEN, &b_true, sizeof(b_true)},
\r
657 {CKA_PRIVATE, &b_private_obj, sizeof(b_private_obj)},
\r
658 {CKA_LABEL, name, StrLen(name)},
\r
659 {CKA_CERTIFICATE_TYPE, &cert_type, sizeof(cert_type)},
\r
660 #if 0 // 失敗するトークンがあるのでこれは使わない
\r
661 {CKA_START_DATE, &start_date, sizeof(start_date)},
\r
662 {CKA_END_DATE, &end_date, sizeof(end_date)},
\r
672 sec->Error = SEC_ERROR_BAD_PARAMETER;
\r
675 if (sec->SessionCreated == false)
\r
677 sec->Error = SEC_ERROR_NO_SESSION;
\r
680 if (sec->LoginFlag == false && private_obj)
\r
682 sec->Error = SEC_ERROR_NOT_LOGIN;
\r
687 b = XToBuf(x, false);
\r
690 sec->Error = SEC_ERROR_INVALID_CERT;
\r
693 if (b->Size > sizeof(value))
\r
697 sec->Error = SEC_ERROR_DATA_TOO_BIG;
\r
700 Copy(value, b->Buf, b->Size);
\r
701 A_SIZE(a, 3) = b->Size;
\r
704 // Subject と Issuer を UTF-8 にエンコードして格納
\r
705 GetPrintNameFromName(w_subject, sizeof(w_subject), x->subject_name);
\r
706 UniToUtf8(subject, sizeof(subject), w_subject);
\r
707 A_SIZE(a, 0) = StrLen(subject);
\r
708 if (x->root_cert == false)
\r
710 GetPrintNameFromName(w_issuer, sizeof(w_issuer), x->issuer_name);
\r
711 UniToUtf8(issuer, sizeof(issuer), w_issuer);
\r
712 A_SIZE(a, 1) = StrLen(issuer);
\r
716 Copy(serial_number, x->serial->data, MIN(x->serial->size, sizeof(serial_number)));
\r
717 A_SIZE(a, 2) = MIN(x->serial->size, sizeof(serial_number));
\r
720 UINT64ToCkDate(&start_date, SystemToLocal64(x->notBefore));
\r
721 UINT64ToCkDate(&end_date, SystemToLocal64(x->notAfter));
\r
723 // 同一の名前のオブジェクトがあれば削除
\r
724 if (CheckSecObject(sec, name, SEC_X))
\r
726 DeleteSecCert(sec, name);
\r
730 if ((ret = sec->Api->C_CreateObject(sec->SessionId, a, sizeof(a) / sizeof(a[0]), &object)) != CKR_OK)
\r
733 sec->Error = SEC_ERROR_HARDWARE_ERROR;
\r
734 Debug("Error: 0x%02x\n", ret);
\r
739 EraseEnumSecObjectCache(sec);
\r
745 bool DeleteSecKey(SECURE *sec, char *name)
\r
747 return DeleteSecObjectByName(sec, name, SEC_K);
\r
751 bool DeleteSecCert(SECURE *sec, char *name)
\r
753 return DeleteSecObjectByName(sec, name, SEC_X);
\r
756 // CK_DATE を 64 bit 時刻に変換
\r
757 UINT64 CkDateToUINT64(struct CK_DATE *ck_date)
\r
760 char year[32], month[32], day[32];
\r
762 if (ck_date == NULL)
\r
767 Zero(year, sizeof(year));
\r
768 Zero(month, sizeof(month));
\r
769 Zero(day, sizeof(day));
\r
771 Copy(year, ck_date->year, 4);
\r
772 Copy(month, ck_date->month, 2);
\r
773 Copy(day, ck_date->day, 2);
\r
775 st.wYear = ToInt(year);
\r
776 st.wMonth = ToInt(month);
\r
777 st.wDay = ToInt(day);
\r
779 return SystemToUINT64(&st);
\r
782 // 64 bit 時刻を CK_DATE に変換
\r
783 void UINT64ToCkDate(void *p_ck_date, UINT64 time64)
\r
786 char year[32], month[32], day[32];
\r
787 struct CK_DATE *ck_date = (CK_DATE *)p_ck_date;
\r
789 if (ck_date == NULL)
\r
794 UINT64ToSystem(&st, time64);
\r
796 Format(year, sizeof(year), "%04u", st.wYear);
\r
797 Format(month, sizeof(month), "%04u", st.wMonth);
\r
798 Format(day, sizeof(day), "%04u", st.wDay);
\r
800 Zero(ck_date, sizeof(CK_DATE));
\r
802 Copy(ck_date->year, year, 4);
\r
803 Copy(ck_date->month, month, 2);
\r
804 Copy(ck_date->day, day, 2);
\r
807 // オブジェクトを名前で指定して削除
\r
808 bool DeleteSecObjectByName(SECURE *sec, char *name, UINT type)
\r
819 sec->Error = SEC_ERROR_BAD_PARAMETER;
\r
822 if (sec->SessionCreated == false)
\r
824 sec->Error = SEC_ERROR_NO_SESSION;
\r
829 obj = FindSecObject(sec, name, type);
\r
837 ret = DeleteSecObject(sec, obj);
\r
840 FreeSecObject(obj);
\r
846 bool DeleteSecData(SECURE *sec, char *name)
\r
855 sec->Error = SEC_ERROR_BAD_PARAMETER;
\r
859 return DeleteSecObjectByName(sec, name, SEC_DATA);
\r
863 bool DeleteSecObject(SECURE *sec, SEC_OBJ *obj)
\r
872 sec->Error = SEC_ERROR_BAD_PARAMETER;
\r
875 if (sec->SessionCreated == false)
\r
877 sec->Error = SEC_ERROR_NO_SESSION;
\r
880 if (sec->LoginFlag == false && obj->Private)
\r
882 sec->Error = SEC_ERROR_NOT_LOGIN;
\r
887 if (sec->Api->C_DestroyObject(sec->SessionId, obj->Object) != CKR_OK)
\r
889 sec->Error = SEC_ERROR_HARDWARE_ERROR;
\r
894 DeleteSecObjFromEnumCache(sec, obj->Name, obj->Type);
\r
899 // キャッシュから指定した名前のオブジェクトを削除する
\r
900 void DeleteSecObjFromEnumCache(SECURE *sec, char *name, UINT type)
\r
904 if (sec == NULL || name == NULL || sec->EnumCache == NULL)
\r
909 for (i = 0;i < LIST_NUM(sec->EnumCache);i++)
\r
911 SEC_OBJ *obj = LIST_DATA(sec->EnumCache, i);
\r
913 if (StrCmpi(obj->Name, name) == 0)
\r
915 if (obj->Type == type)
\r
917 Delete(sec->EnumCache, obj);
\r
918 FreeSecObject(obj);
\r
925 // セキュアオブジェクトを名前で検索して読み込む
\r
926 int ReadSecData(SECURE *sec, char *name, void *data, UINT size)
\r
931 if (sec == NULL || name == NULL || data == NULL)
\r
935 if (sec->SessionCreated == false)
\r
937 sec->Error = SEC_ERROR_NO_SESSION;
\r
942 obj = FindSecObject(sec, name, SEC_DATA);
\r
950 ret = ReadSecDataFromObject(sec, obj, data, size);
\r
952 FreeSecObject(obj);
\r
958 void EraseEnumSecObjectCache(SECURE *sec)
\r
961 if (sec == NULL || sec->EnumCache == NULL)
\r
966 FreeEnumSecObject(sec->EnumCache);
\r
967 sec->EnumCache = NULL;
\r
970 // セキュアオブジェクトの存在をチェックする
\r
971 bool CheckSecObject(SECURE *sec, char *name, UINT type)
\r
981 sec->Error = SEC_ERROR_BAD_PARAMETER;
\r
984 if (sec->SessionCreated == false)
\r
986 sec->Error = SEC_ERROR_NO_SESSION;
\r
990 obj = FindSecObject(sec, name, type);
\r
998 FreeSecObject(obj);
\r
1003 // セキュアオブジェクト構造体のクローンの作成
\r
1004 SEC_OBJ *CloneSecObject(SEC_OBJ *obj)
\r
1013 ret = ZeroMalloc(sizeof(SEC_OBJ));
\r
1014 ret->Name = CopyStr(obj->Name);
\r
1015 ret->Object = obj->Object;
\r
1016 ret->Private = obj->Private;
\r
1017 ret->Type = obj->Type;
\r
1022 // セキュアオブジェクトを名前で検索して取得する
\r
1023 SEC_OBJ *FindSecObject(SECURE *sec, char *name, UINT type)
\r
1027 SEC_OBJ *ret = NULL;
\r
1035 sec->Error = SEC_ERROR_BAD_PARAMETER;
\r
1038 if (sec->SessionCreated == false)
\r
1040 sec->Error = SEC_ERROR_NO_SESSION;
\r
1045 o = EnumSecObject(sec);
\r
1050 for (i = 0;i < LIST_NUM(o);i++)
\r
1052 SEC_OBJ *obj = LIST_DATA(o, i);
\r
1054 if (obj->Type == type || type == INFINITE)
\r
1056 if (StrCmpi(obj->Name, name) == 0)
\r
1058 ret = CloneSecObject(obj);
\r
1063 FreeEnumSecObject(o);
\r
1067 sec->Error = SEC_ERROR_OBJ_NOT_FOUND;
\r
1073 // セキュアオブジェクトの読み込み
\r
1074 int ReadSecDataFromObject(SECURE *sec, SEC_OBJ *obj, void *data, UINT size)
\r
1076 UCHAR buf[MAX_SEC_DATA_SIZE];
\r
1078 CK_ATTRIBUTE get[] =
\r
1080 {CKA_VALUE, buf, sizeof(buf)},
\r
1087 if (obj == NULL || data == NULL || size == 0)
\r
1089 sec->Error = SEC_ERROR_BAD_PARAMETER;
\r
1092 if (obj->Type != SEC_DATA)
\r
1094 sec->Error = SEC_ERROR_BAD_PARAMETER;
\r
1097 if (sec->SessionCreated == false)
\r
1099 sec->Error = SEC_ERROR_NO_SESSION;
\r
1102 if (sec->LoginFlag == false && obj->Private)
\r
1104 sec->Error = SEC_ERROR_NOT_LOGIN;
\r
1109 if (sec->Api->C_GetAttributeValue(
\r
1110 sec->SessionId, obj->Object, get, sizeof(get) / sizeof(get[0])) != CKR_OK)
\r
1112 sec->Error = SEC_ERROR_HARDWARE_ERROR;
\r
1117 i = get[0].ulValueLen;
\r
1118 if (i > MAX_SEC_DATA_SIZE || i > size)
\r
1121 sec->Error = SEC_ERROR_DATA_TOO_BIG;
\r
1126 Copy(data, buf, i);
\r
1131 // セキュアオブジェクトの列挙結果の解放
\r
1132 void FreeEnumSecObject(LIST *o)
\r
1141 for (i = 0;i < LIST_NUM(o);i++)
\r
1143 SEC_OBJ *obj = LIST_DATA(o, i);
\r
1145 FreeSecObject(obj);
\r
1152 void FreeSecObject(SEC_OBJ *obj)
\r
1164 // セキュアオブジェクト列挙結果のクローン
\r
1165 LIST *CloneEnumSecObject(LIST *o)
\r
1175 ret = NewListFast(NULL);
\r
1176 for (i = 0;i < LIST_NUM(o);i++)
\r
1178 SEC_OBJ *obj = LIST_DATA(o, i);
\r
1180 Add(ret, CloneSecObject(obj));
\r
1187 LIST *EnumSecObject(SECURE *sec)
\r
1189 CK_BBOOL b_true = true, b_false = false;
\r
1190 UINT objects[MAX_OBJ];
\r
1194 CK_ATTRIBUTE dummy[1];
\r
1195 CK_ATTRIBUTE a[] =
\r
1197 {CKA_TOKEN, &b_true, sizeof(b_true)},
\r
1199 UINT num_objects = MAX_OBJ;
\r
1205 if (sec->SessionCreated == false)
\r
1207 sec->Error = SEC_ERROR_NO_SESSION;
\r
1211 Zero(dummy, sizeof(dummy));
\r
1213 // キャッシュがあればキャッシュを返す
\r
1214 if (sec->EnumCache != NULL)
\r
1216 return CloneEnumSecObject(sec->EnumCache);
\r
1220 // if (sec->Dev->Id != 2 && sec->Dev->Id != 14)
\r
1223 ret = sec->Api->C_FindObjectsInit(sec->SessionId, a, sizeof(a) / sizeof(a[0]));
\r
1227 // ePass と SafeSign
\r
1228 // ret = sec->Api->C_FindObjectsInit(sec->SessionId, dummy, 0);
\r
1231 if (ret != CKR_OK)
\r
1233 sec->Error = SEC_ERROR_HARDWARE_ERROR;
\r
1236 if (sec->Api->C_FindObjects(sec->SessionId, objects, sizeof(objects) / sizeof(objects[0]), &num_objects) != CKR_OK)
\r
1238 sec->Api->C_FindObjectsFinal(sec->SessionId);
\r
1239 sec->Error = SEC_ERROR_HARDWARE_ERROR;
\r
1242 sec->Api->C_FindObjectsFinal(sec->SessionId);
\r
1244 o = NewListFast(NULL);
\r
1246 for (i = 0;i < num_objects;i++)
\r
1248 char label[MAX_SIZE];
\r
1249 UINT obj_class = 0;
\r
1250 bool priv = false;
\r
1251 CK_ATTRIBUTE get[] =
\r
1253 {CKA_LABEL, label, sizeof(label) - 1},
\r
1254 {CKA_CLASS, &obj_class, sizeof(obj_class)},
\r
1255 {CKA_PRIVATE, &priv, sizeof(priv)},
\r
1258 Zero(label, sizeof(label));
\r
1260 if (sec->Api->C_GetAttributeValue(sec->SessionId, objects[i],
\r
1261 get, sizeof(get) / sizeof(get[0])) == CKR_OK)
\r
1263 UINT type = INFINITE;
\r
1265 switch (obj_class)
\r
1272 case CKO_CERTIFICATE:
\r
1277 case CKO_PUBLIC_KEY:
\r
1282 case CKO_PRIVATE_KEY:
\r
1288 if (type != INFINITE)
\r
1290 SEC_OBJ *obj = ZeroMalloc(sizeof(SEC_OBJ));
\r
1293 obj->Object = objects[i];
\r
1294 obj->Private = (priv == false) ? false : true;
\r
1295 EnSafeStr(label, '?');
\r
1296 TruncateCharFromStr(label, '?');
\r
1297 obj->Name = CopyStr(label);
\r
1305 sec->EnumCache = CloneEnumSecObject(o);
\r
1311 bool WriteSecData(SECURE *sec, bool private_obj, char *name, void *data, UINT size)
\r
1313 UINT object_class = CKO_DATA;
\r
1314 CK_BBOOL b_true = true, b_false = false, b_private_obj = private_obj;
\r
1316 CK_ATTRIBUTE a[] =
\r
1318 {CKA_TOKEN, &b_true, sizeof(b_true)},
\r
1319 {CKA_CLASS, &object_class, sizeof(object_class)},
\r
1320 {CKA_PRIVATE, &b_private_obj, sizeof(b_private_obj)},
\r
1321 {CKA_LABEL, name, StrLen(name)},
\r
1322 {CKA_VALUE, data, size},
\r
1329 if (sec->SessionCreated == false)
\r
1331 sec->Error = SEC_ERROR_NO_SESSION;
\r
1334 if (private_obj && sec->LoginFlag == false)
\r
1336 sec->Error = SEC_ERROR_NOT_LOGIN;
\r
1339 if (name == NULL || data == NULL || size == 0)
\r
1341 sec->Error = SEC_ERROR_BAD_PARAMETER;
\r
1344 if (size > MAX_SEC_DATA_SIZE)
\r
1346 sec->Error = SEC_ERROR_DATA_TOO_BIG;
\r
1350 // 同名のオブジェクトがあれば削除
\r
1351 if (CheckSecObject(sec, name, SEC_DATA))
\r
1353 DeleteSecData(sec, name);
\r
1357 if (sec->Api->C_CreateObject(sec->SessionId, a, sizeof(a) / sizeof(a[0]), &object) != CKR_OK)
\r
1359 sec->Error = SEC_ERROR_HARDWARE_ERROR;
\r
1364 EraseEnumSecObjectCache(sec);
\r
1369 // キャッシュに新規作成したオブジェクトの情報を追加する
\r
1370 void AddSecObjToEnumCache(SECURE *sec, char *name, UINT type, bool private_obj, UINT object)
\r
1374 if (sec == NULL || name == NULL || sec->EnumCache == NULL)
\r
1379 obj = ZeroMalloc(sizeof(SEC_OBJ));
\r
1380 obj->Name = CopyStr(name);
\r
1381 obj->Object = object;
\r
1382 obj->Private = private_obj;
\r
1385 Add(sec->EnumCache, obj);
\r
1389 void PrintSecInfo(SECURE *sec)
\r
1401 Print("No Token Info.\n");
\r
1407 " ManufacturerId: %S\n"
\r
1409 " SerialNumber: %S\n"
\r
1410 " MaxSession: %u\n"
\r
1411 " MaxRWSession: %u\n"
\r
1412 " MinPinLen: %u\n"
\r
1413 " MaxPinLen: %u\n"
\r
1414 " TotalPublicMemory: %u\n"
\r
1415 " FreePublicMemory: %u\n"
\r
1416 " TotalPrivateMemory: %u\n"
\r
1417 " FreePrivateMemory: %u\n"
\r
1418 " HardwareVersion: %s\n"
\r
1419 " FirmwareVersion: %s\n",
\r
1420 s->Label, s->ManufacturerId, s->Model, s->SerialNumber,
\r
1421 s->MaxSession, s->MaxRWSession, s->MinPinLen, s->MaxPinLen,
\r
1422 s->TotalPublicMemory, s->FreePublicMemory, s->TotalPrivateMemory,
\r
1423 s->FreePrivateMemory, s->HardwareVersion, s->FirmwareVersion
\r
1428 void GetSecInfo(SECURE *sec)
\r
1430 CK_TOKEN_INFO token_info;
\r
1436 if (sec->Info != NULL)
\r
1442 Zero(&token_info, sizeof(token_info));
\r
1443 if (sec->Api->C_GetTokenInfo(sec->SlotIdList[sec->SessionSlotNumber], &token_info) != CKR_OK)
\r
1449 sec->Info = TokenInfoToSecInfo(&token_info);
\r
1453 void FreeSecInfo(SECURE *sec)
\r
1460 if (sec->Info == NULL)
\r
1465 FreeSecInfoMemory(sec->Info);
\r
1469 // トークン情報を SEC_INFO に変換
\r
1470 SEC_INFO *TokenInfoToSecInfo(void *p_t)
\r
1473 char buf[MAX_SIZE];
\r
1474 CK_TOKEN_INFO *t = (CK_TOKEN_INFO *)p_t;
\r
1481 s = ZeroMalloc(sizeof(SEC_INFO));
\r
1484 Zero(buf, sizeof(buf));
\r
1485 Copy(buf, t->label, sizeof(t->label));
\r
1486 s->Label = ZeroMalloc(CalcUtf8ToUni(buf, 0));
\r
1487 Utf8ToUni(s->Label, 0, buf, 0);
\r
1490 Zero(buf, sizeof(buf));
\r
1491 Copy(buf, t->manufacturerID, sizeof(t->manufacturerID));
\r
1492 s->ManufacturerId = ZeroMalloc(CalcUtf8ToUni(buf, 0));
\r
1493 Utf8ToUni(s->ManufacturerId, 0, buf, 0);
\r
1496 Zero(buf, sizeof(buf));
\r
1497 Copy(buf, t->model, sizeof(t->model));
\r
1498 s->Model = ZeroMalloc(CalcUtf8ToUni(buf, 0));
\r
1499 Utf8ToUni(s->Model, 0, buf, 0);
\r
1502 Zero(buf, sizeof(buf));
\r
1503 Copy(buf, t->serialNumber, sizeof(t->serialNumber));
\r
1504 s->SerialNumber = ZeroMalloc(CalcUtf8ToUni(buf, 0));
\r
1505 Utf8ToUni(s->SerialNumber, 0, buf, 0);
\r
1508 s->MaxSession = t->ulMaxSessionCount;
\r
1509 s->MaxRWSession = t->ulMaxRwSessionCount;
\r
1510 s->MinPinLen = t->ulMinPinLen;
\r
1511 s->MaxPinLen = t->ulMaxPinLen;
\r
1512 s->TotalPublicMemory = t->ulTotalPublicMemory;
\r
1513 s->FreePublicMemory = t->ulFreePublicMemory;
\r
1514 s->TotalPrivateMemory = t->ulTotalPrivateMemory;
\r
1515 s->FreePrivateMemory = t->ulFreePrivateMemory;
\r
1518 Format(buf, sizeof(buf), "%u.%02u", t->hardwareVersion.major, t->hardwareVersion.minor);
\r
1519 s->HardwareVersion = CopyStr(buf);
\r
1522 Format(buf, sizeof(buf), "%u.%02u", t->firmwareVersion.major, t->firmwareVersion.minor);
\r
1523 s->FirmwareVersion = CopyStr(buf);
\r
1528 // SEC_INFO のメモリを解放
\r
1529 void FreeSecInfoMemory(SEC_INFO *s)
\r
1538 Free(s->ManufacturerId);
\r
1540 Free(s->SerialNumber);
\r
1541 Free(s->HardwareVersion);
\r
1542 Free(s->FirmwareVersion);
\r
1547 void LogoutSec(SECURE *sec)
\r
1554 if (sec->LoginFlag == false)
\r
1560 sec->Api->C_Logout(sec->SessionId);
\r
1563 EraseEnumSecObjectCache(sec);
\r
1565 sec->LoginFlag = false;
\r
1569 bool LoginSec(SECURE *sec, char *pin)
\r
1576 if (sec->SessionCreated == false)
\r
1578 sec->Error = SEC_ERROR_NO_SESSION;
\r
1582 if (sec->LoginFlag)
\r
1584 sec->Error = SEC_ERROR_ALREADY_LOGIN;
\r
1589 sec->Error = SEC_ERROR_NO_PIN_STR;
\r
1594 if (sec->Api->C_Login(sec->SessionId, CKU_USER, pin, StrLen(pin)) != CKR_OK)
\r
1597 sec->Error = SEC_ERROR_BAD_PIN_CODE;
\r
1602 EraseEnumSecObjectCache(sec);
\r
1604 sec->LoginFlag = true;
\r
1610 void CloseSecSession(SECURE *sec)
\r
1617 if (sec->SessionCreated == false)
\r
1623 sec->Api->C_CloseSession(sec->SessionId);
\r
1625 sec->SessionCreated = false;
\r
1626 sec->SessionId = 0;
\r
1627 sec->SessionSlotNumber = 0;
\r
1632 EraseEnumSecObjectCache(sec);
\r
1636 bool OpenSecSession(SECURE *sec, UINT slot_number)
\r
1645 if (sec->SessionCreated)
\r
1648 sec->Error = SEC_ERROR_SESSION_EXISTS;
\r
1651 if (slot_number >= sec->NumSlot)
\r
1654 sec->Error = SEC_ERROR_INVALID_SLOT_NUMBER;
\r
1659 if ((err = sec->Api->C_OpenSession(sec->SlotIdList[slot_number],
\r
1660 CKF_RW_SESSION | CKF_SERIAL_SESSION, NULL, NULL, &session)) != CKR_OK)
\r
1662 // 読み書きモードでのセッション初期化に失敗した
\r
1664 if ((err = sec->Api->C_OpenSession(sec->SlotIdList[slot_number],
\r
1665 CKF_SERIAL_SESSION, NULL, NULL, &session)) != CKR_OK)
\r
1668 sec->Error = SEC_ERROR_OPEN_SESSION;
\r
1673 sec->IsReadOnly = true;
\r
1677 sec->SessionCreated = true;
\r
1678 sec->SessionId = session;
\r
1679 sec->SessionSlotNumber = slot_number;
\r
1688 void CloseSec(SECURE *sec)
\r
1700 CloseSecSession(sec);
\r
1706 if (sec->SlotIdList != NULL)
\r
1708 Free(sec->SlotIdList);
\r
1709 sec->SlotIdList = NULL;
\r
1713 FreeSecModule(sec);
\r
1716 DeleteLock(sec->lock);
\r
1721 SECURE *OpenSec(UINT id)
\r
1723 SECURE_DEVICE *dev = GetSecureDevice(id);
\r
1732 sec = ZeroMalloc(sizeof(SECURE));
\r
1734 sec->lock = NewLock();
\r
1735 sec->Error = SEC_ERROR_NOERROR;
\r
1739 if (SearchStrEx(dev->DeviceName, "epass", 0, false) != INFINITE)
\r
1741 sec->IsEPass1000 = true;
\r
1745 if (LoadSecModule(sec) == false)
\r
1753 if ((err = sec->Api->C_GetSlotList(true, NULL, &sec->NumSlot)) != CKR_OK || sec->NumSlot == 0)
\r
1756 FreeSecModule(sec);
\r
1761 sec->SlotIdList = (UINT *)ZeroMalloc(sizeof(UINT *) * sec->NumSlot);
\r
1763 if (sec->Api->C_GetSlotList(TRUE, sec->SlotIdList, &sec->NumSlot) != CKR_OK)
\r
1766 Free(sec->SlotIdList);
\r
1767 sec->SlotIdList = NULL;
\r
1768 FreeSecModule(sec);
\r
1776 // セキュアデバイスのモジュールをロードする
\r
1777 bool LoadSecModule(SECURE *sec)
\r
1787 ret = Win32LoadSecModule(sec);
\r
1788 #endif // OS_WIN32
\r
1791 if (sec->Api->C_Initialize(NULL) != CKR_OK)
\r
1794 FreeSecModule(sec);
\r
1798 sec->Initialized = true;
\r
1803 // セキュアデバイスのモジュールをアンロードする
\r
1804 void FreeSecModule(SECURE *sec)
\r
1812 if (sec->Initialized)
\r
1815 sec->Api->C_Finalize(NULL);
\r
1816 sec->Initialized = false;
\r
1820 Win32FreeSecModule(sec);
\r
1821 #endif // OS_WIN32
\r
1827 SECURE_DEVICE *GetSecureDevice(UINT id)
\r
1836 for (i = 0;i < LIST_NUM(SecureDeviceList);i++)
\r
1838 SECURE_DEVICE *dev = LIST_DATA(SecureDeviceList, i);
\r
1840 if (dev->Id == id)
\r
1849 // セキュアデバイスの ID を確認する
\r
1850 bool CheckSecureDeviceId(UINT id)
\r
1854 for (i = 0;i < LIST_NUM(SecureDeviceList);i++)
\r
1856 SECURE_DEVICE *dev = LIST_DATA(SecureDeviceList, i);
\r
1858 if (dev->Id == id)
\r
1867 // サポートされているデバイスリストを取得する
\r
1868 LIST *GetSecureDeviceList()
\r
1870 return GetSupportedDeviceList();
\r
1873 // サポートされているデバイスリストを取得する
\r
1874 LIST *GetSupportedDeviceList()
\r
1877 AddRef(SecureDeviceList->ref);
\r
1879 return SecureDeviceList;
\r
1882 // 指定したデバイスがインストールされていて利用可能かどうか調べる
\r
1883 bool IsDeviceSupported(SECURE_DEVICE *dev)
\r
1887 b = Win32IsDeviceSupported(dev);
\r
1888 #endif // OS_WIN32
\r
1892 // セキュアデバイスリストの初期化
\r
1893 void InitSecureDeviceList()
\r
1895 UINT i, num_supported_list;
\r
1896 SecureDeviceList = NewList(NULL);
\r
1898 num_supported_list = sizeof(SupportedList) / sizeof(SECURE_DEVICE);
\r
1899 for (i = 0; i < num_supported_list;i++)
\r
1901 SECURE_DEVICE *dev = &SupportedList[i];
\r
1904 if (IsDeviceSupported(dev))
\r
1906 // サポートされているのでリストに追加
\r
1907 Add(SecureDeviceList, dev);
\r
1913 void TestSecMain(SECURE *sec)
\r
1915 char *test_str = "SoftEther UT-VPN";
\r
1916 K *public_key, *private_key;
\r
1923 Print("test_str: \"%s\"\n", test_str);
\r
1925 Print("Writing Data...\n");
\r
1926 if (WriteSecData(sec, true, "test_str", test_str, StrLen(test_str)) == false)
\r
1928 Print("WriteSecData() Failed.\n");
\r
1932 char data[MAX_SIZE];
\r
1933 Zero(data, sizeof(data));
\r
1934 Print("Reading Data...\n");
\r
1935 if (ReadSecData(sec, "test_str", data, sizeof(data)) == false)
\r
1937 Print("ReadSecData() Failed.\n");
\r
1941 Print("test_str: \"%s\"\n", data);
\r
1943 Print("Deleting Data...\n");
\r
1944 DeleteSecData(sec, "test_str");
\r
1947 Print("Generating Key...\n");
\r
1948 if (RsaGen(&private_key, &public_key, 1024) == false)
\r
1950 Print("RsaGen() Failed.\n");
\r
1957 UINT num = 0x11220000;
\r
1959 Print("Creating Cert...\n");
\r
1960 serial = NewXSerial(&num, sizeof(UINT));
\r
1961 name = NewName(L"Test", L"Test", L"Test", L"JP", L"Test", L"Test");
\r
1962 cert = NewRootX(public_key, private_key, name, 365, NULL);
\r
1963 FreeXSerial(serial);
\r
1966 Print("NewRootX() Failed.\n");
\r
1970 Print("Writing Cert...\n");
\r
1971 DeleteSecData(sec, "test_cer");
\r
1972 if (WriteSecCert(sec, true, "test_cer", cert) == false)
\r
1974 Print("WriteSecCert() Failed.\n");
\r
1979 Print("Reading Cert...\n");
\r
1980 x = ReadSecCert(sec, "test_cer");
\r
1983 Print("ReadSecCert() Failed.\n");
\r
1987 Print("Checking two Certs... ");
\r
1988 if (CompareX(x, cert) == false)
\r
1990 Print("[FAILED]\n");
\r
2001 XToFile(cert, "cert_tmp.cer", true);
\r
2002 x = FileToX("cert_tmp.cer");
\r
2003 if (CompareX(x, cert) == false)
\r
2005 Print("[FAILED]\n");
\r
2010 Print("Writing Private Key...\n");
\r
2011 DeleteSecKey(sec, "test_key");
\r
2012 if (WriteSecKey(sec, true, "test_key", private_key) == false)
\r
2014 Print("WriteSecKey() Failed.\n");
\r
2018 UCHAR sign_cpu[128];
\r
2019 UCHAR sign_sec[128];
\r
2020 K *pub = GetKFromX(cert);
\r
2022 Print("Signing Data by CPU...\n");
\r
2023 if (RsaSign(sign_cpu, test_str, StrLen(test_str), private_key) == false)
\r
2025 Print("RsaSign() Failed.\n");
\r
2030 Print("sign_cpu: ");
\r
2031 PrintBin(sign_cpu, sizeof(sign_cpu));
\r
2032 Print("Signing Data by %s..\n", sec->Dev->DeviceName);
\r
2033 if (SignSec(sec, "test_key", sign_sec, test_str, StrLen(test_str)) == false)
\r
2035 Print("SignSec() Failed.\n");
\r
2040 Print("sign_sec: ");
\r
2041 PrintBin(sign_sec, sizeof(sign_sec));
\r
2042 Print("Compare...");
\r
2043 if (Cmp(sign_sec, sign_cpu, sizeof(sign_cpu)) == 0)
\r
2046 Print("Verify...");
\r
2047 if (RsaVerify(test_str, StrLen(test_str),
\r
2048 sign_sec, pub) == false)
\r
2050 Print("[FAILED]\n");
\r
2059 Print("[DIFFIRENT]\n");
\r
2063 Print("Deleting test_key...\n");
\r
2064 // DeleteSecKey(sec, "test_key");
\r
2071 Print("Deleting Cert..\n");
\r
2072 // DeleteSecCert(sec, "test_cer");
\r
2076 FreeK(private_key);
\r
2077 FreeK(public_key);
\r
2085 LIST *secure_device_list;
\r
2086 Print("Secure Device Test Program\n"
\r
2087 "Copyright (C) 2004-2010 SoftEther Corporation. All Rights Reserved.\n\n");
\r
2090 secure_device_list = GetSecureDeviceList();
\r
2091 if (secure_device_list != NULL)
\r
2093 UINT use_device_id;
\r
2094 char tmp[MAX_SIZE];
\r
2095 Print("--- Secure Device List ---\n");
\r
2096 for (i = 0;i < LIST_NUM(secure_device_list);i++)
\r
2098 SECURE_DEVICE *dev = LIST_DATA(secure_device_list, i);
\r
2099 Print("%2u - %s\n", dev->Id, dev->DeviceName);
\r
2102 Print("Device ID >");
\r
2103 GetLine(tmp, sizeof(tmp));
\r
2104 use_device_id = ToInt(tmp);
\r
2105 if (use_device_id == 0)
\r
2107 Print("Canceled.\n");
\r
2111 SECURE *sec = OpenSec(use_device_id);
\r
2112 Print("Opening Device...\n");
\r
2115 Print("OpenSec() Failed.\n");
\r
2119 Print("Opening Session...\n");
\r
2120 if (OpenSecSession(sec, 0) == false)
\r
2122 Print("OpenSecSession() Failed.\n");
\r
2128 char pin[MAX_SIZE];
\r
2129 Print("PIN Code >");
\r
2130 GetLine(pin, sizeof(pin));
\r
2132 if (StrLen(pin) == 0)
\r
2134 Print("Canceled.\n");
\r
2139 Print("Login...\n");
\r
2140 if (LoginSec(sec, pin))
\r
2143 Print("Logout...\n");
\r
2149 Print("Login Failed. Please Try Again.\n");
\r
2153 Print("Closing Session...\n");
\r
2154 CloseSecSession(sec);
\r
2156 Print("Closing Device...\n");
\r
2160 ReleaseList(secure_device_list);
\r
2164 Print("GetSecureDeviceList() Error.\n");
\r
2169 void FreeSecureDeviceList()
\r
2171 ReleaseList(SecureDeviceList);
\r
2174 // セキュリティトークンモジュールの初期化
\r
2177 // セキュアデバイスリストの初期化
\r
2178 InitSecureDeviceList();
\r
2181 // セキュリティトークンモジュールの解放
\r
2185 FreeSecureDeviceList();
\r