| 1 | // SoftEther UT-VPN SourceCode | 
|---|
| 2 | //  | 
|---|
| 3 | // Copyright (C) 2004-2010 SoftEther Corporation. | 
|---|
| 4 | // Copyright (C) 2004-2010 University of Tsukuba, Japan. | 
|---|
| 5 | // Copyright (C) 2003-2010 Daiyuu Nobori. | 
|---|
| 6 | // All Rights Reserved. | 
|---|
| 7 | //  | 
|---|
| 8 | // http://utvpn.tsukuba.ac.jp/ | 
|---|
| 9 | //  | 
|---|
| 10 | // This program is free software; you can redistribute it and/or | 
|---|
| 11 | // modify it under the terms of the GNU General Public License | 
|---|
| 12 | // version 2 as published by the Free Software Foundation. | 
|---|
| 13 | //  | 
|---|
| 14 | // This program is distributed in the hope that it will be useful, | 
|---|
| 15 | // but WITHOUT ANY WARRANTY; without even the implied warranty of | 
|---|
| 16 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | 
|---|
| 17 | // GNU General Public License for more details. | 
|---|
| 18 | //  | 
|---|
| 19 | // You should have received a copy of the GNU General Public License version 2 | 
|---|
| 20 | // along with this program; if not, write to the Free Software | 
|---|
| 21 | // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. | 
|---|
| 22 | //  | 
|---|
| 23 | // このファイルは GPL バージョン 2 ライセンスで公開されています。 | 
|---|
| 24 | // 誰でもこのファイルの内容を複製、改変したり、改変したバージョンを再配布 | 
|---|
| 25 | // することができます。ただし、原著作物を改変した場合は、原著作物の著作権表示 | 
|---|
| 26 | // を除去することはできません。改変した著作物を配布する場合は、改変実施者の | 
|---|
| 27 | // 著作権表示を原著作物の著作権表示に付随して記載するようにしてください。 | 
|---|
| 28 | //  | 
|---|
| 29 | // この SoftEther UT-VPN オープンソース・プロジェクトは、日本国の | 
|---|
| 30 | // ソフトイーサ株式会社 (SoftEther Corporation, http://www.softether.co.jp/ ) | 
|---|
| 31 | // および筑波大学 (University of Tsukuba, http://www.tsukuba.ac.jp/ ) によって | 
|---|
| 32 | // ホストされています。 | 
|---|
| 33 | // 本プログラムの配布者は、本プログラムを、業としての利用以外のため、 | 
|---|
| 34 | // および、試験または研究のために利用が行われることを想定して配布 | 
|---|
| 35 | // しています。 | 
|---|
| 36 | // SoftEther UT-VPN プロジェクトの Web サイトは http://utvpn.tsukuba.ac.jp/ に | 
|---|
| 37 | // あります。 | 
|---|
| 38 | // 本ソフトウェアの不具合の修正、機能改良、セキュリティホールの修復などのコード | 
|---|
| 39 | // の改変を行った場合で、その成果物を SoftEther UT-VPN プロジェクトに提出して | 
|---|
| 40 | // いただける場合は、 http://utvpn.tsukuba.ac.jp/ までソースコードを送付して | 
|---|
| 41 | // ください。SoftEther UT-VPN プロジェクトの本体リリースまたはブランチリリース | 
|---|
| 42 | // に組み込みさせていただきます。 | 
|---|
| 43 | //  | 
|---|
| 44 | // GPL に基づいて原著作物が提供される本ソフトウェアの改良版を配布、販売する | 
|---|
| 45 | // 場合は、そのソースコードを GPL に基づいて誰にでも開示する義務が生じます。 | 
|---|
| 46 | //  | 
|---|
| 47 | // 本ソフトウェアに関連する著作権、特許権、商標権はソフトイーサ株式会社 | 
|---|
| 48 | // (SoftEther Corporation) およびその他の著作権保持者が保有しています。 | 
|---|
| 49 | // ソフトイーサ株式会社等はこれらの権利を放棄していません。本ソフトウェアの | 
|---|
| 50 | // 二次著作物を配布、販売する場合は、これらの権利を侵害しないようにご注意 | 
|---|
| 51 | // ください。 | 
|---|
| 52 | //  | 
|---|
| 53 | // お願い: どのような通信ソフトウェアにも通常は必ず未発見の | 
|---|
| 54 | // セキュリティホールが潜んでいます。本ソースコードをご覧いただいた結果、 | 
|---|
| 55 | // UT-VPN にセキュリティホールを発見された場合は、当該セキュリティホールの | 
|---|
| 56 | // 情報を不特定多数に開示される前に、必ず、ソフトイーサ株式会社 | 
|---|
| 57 | // および脆弱性情報の届出を受け付ける公的機関まで通報いただき、 | 
|---|
| 58 | // 公益保護にご協力いただきますようお願い申し上げます。 | 
|---|
| 59 | //  | 
|---|
| 60 | // ソフトイーサ株式会社は、当該セキュリティホールについて迅速に対処を | 
|---|
| 61 | // 行い、UT-VPN および UT-VPN に関連するソフトウェアのユーザー・顧客 | 
|---|
| 62 | // を保護するための努力を行います。 | 
|---|
| 63 | //  | 
|---|
| 64 | // ソフトイーサへの届出先: http://www.softether.co.jp/jp/contact/ | 
|---|
| 65 | // 日本国内の脆弱性情報届出受付公的機関: | 
|---|
| 66 | //         独立行政法人 情報処理推進機構 | 
|---|
| 67 | //         http://www.ipa.go.jp/security/vuln/report/ | 
|---|
| 68 | //  | 
|---|
| 69 | // 上記各事項について不明な点は、ソフトイーサ株式会社までご連絡ください。 | 
|---|
| 70 | // 連絡先: http://www.softether.co.jp/jp/contact/ | 
|---|
| 71 |  | 
|---|
| 72 | // ----------------------------------------------- | 
|---|
| 73 | // [ChangeLog] | 
|---|
| 74 | // 2010.05.20 | 
|---|
| 75 | //  新規リリース by SoftEther | 
|---|
| 76 | // ----------------------------------------------- | 
|---|
| 77 |  | 
|---|
| 78 | // Secure.c | 
|---|
| 79 | // セキュリティトークン管理モジュール | 
|---|
| 80 |  | 
|---|
| 81 | #define SECURE_C | 
|---|
| 82 | #define ENCRYPT_C | 
|---|
| 83 |  | 
|---|
| 84 | #ifdef  WIN32 | 
|---|
| 85 | #include <windows.h> | 
|---|
| 86 | #endif  // WIN32 | 
|---|
| 87 |  | 
|---|
| 88 | #include <stdio.h> | 
|---|
| 89 | #include <stdlib.h> | 
|---|
| 90 | #include <string.h> | 
|---|
| 91 | #include <wchar.h> | 
|---|
| 92 | #include <stdarg.h> | 
|---|
| 93 | #include <time.h> | 
|---|
| 94 | #include <errno.h> | 
|---|
| 95 | #include <openssl/ssl.h> | 
|---|
| 96 | #include <openssl/err.h> | 
|---|
| 97 | #include <openssl/rand.h> | 
|---|
| 98 | #include <openssl/engine.h> | 
|---|
| 99 | #include <openssl/bio.h> | 
|---|
| 100 | #include <openssl/x509.h> | 
|---|
| 101 | #include <openssl/pkcs7.h> | 
|---|
| 102 | #include <openssl/pkcs12.h> | 
|---|
| 103 | #include <openssl/rc4.h> | 
|---|
| 104 | #include <openssl/md5.h> | 
|---|
| 105 | #include <openssl/sha.h> | 
|---|
| 106 | #include <Mayaqua/Mayaqua.h> | 
|---|
| 107 | #include <Mayaqua/cryptoki.h> | 
|---|
| 108 |  | 
|---|
| 109 |  | 
|---|
| 110 | #define MAX_OBJ             1024        // ハードウェア内の最大オブジェクト数 (想定) | 
|---|
| 111 |  | 
|---|
| 112 | #define A_SIZE(a, i)        (a[(i)].ulValueLen) | 
|---|
| 113 | #define A_SET(a, i, value, size)    (a[i].pValue = value;a[i].ulValueLen = size;) | 
|---|
| 114 |  | 
|---|
| 115 | #ifdef  OS_WIN32 | 
|---|
| 116 | // Win32 用コード | 
|---|
| 117 |  | 
|---|
| 118 | // Win32 用 DLL 読み込み | 
|---|
| 119 | HINSTANCE Win32SecureLoadLibraryEx(char *dllname, DWORD flags) | 
|---|
| 120 | { | 
|---|
| 121 |     char tmp1[MAX_PATH]; | 
|---|
| 122 |     char tmp2[MAX_PATH]; | 
|---|
| 123 |     char tmp3[MAX_PATH]; | 
|---|
| 124 |     HINSTANCE h; | 
|---|
| 125 |     // 引数チェック | 
|---|
| 126 |     if (dllname == NULL) | 
|---|
| 127 |     { | 
|---|
| 128 |         return NULL; | 
|---|
| 129 |     } | 
|---|
| 130 |  | 
|---|
| 131 |     Format(tmp1, sizeof(tmp1), "%s\\%s", MsGetSystem32Dir(), dllname); | 
|---|
| 132 |     Format(tmp2, sizeof(tmp2), "%s\\JPKI\\%s", MsGetProgramFilesDir(), dllname); | 
|---|
| 133 |     Format(tmp3, sizeof(tmp3), "%s\\LGWAN\\%s", MsGetProgramFilesDir(), dllname); | 
|---|
| 134 |  | 
|---|
| 135 |     h = LoadLibraryEx(dllname, NULL, flags); | 
|---|
| 136 |     if (h != NULL) | 
|---|
| 137 |     { | 
|---|
| 138 |         return h; | 
|---|
| 139 |     } | 
|---|
| 140 |  | 
|---|
| 141 |     h = LoadLibraryEx(tmp1, NULL, flags); | 
|---|
| 142 |     if (h != NULL) | 
|---|
| 143 |     { | 
|---|
| 144 |         return h; | 
|---|
| 145 |     } | 
|---|
| 146 |  | 
|---|
| 147 |     h = LoadLibraryEx(tmp2, NULL, flags); | 
|---|
| 148 |     if (h != NULL) | 
|---|
| 149 |     { | 
|---|
| 150 |         return h; | 
|---|
| 151 |     } | 
|---|
| 152 |  | 
|---|
| 153 |     h = LoadLibraryEx(tmp3, NULL, flags); | 
|---|
| 154 |     if (h != NULL) | 
|---|
| 155 |     { | 
|---|
| 156 |         return h; | 
|---|
| 157 |     } | 
|---|
| 158 |  | 
|---|
| 159 |     return NULL; | 
|---|
| 160 | } | 
|---|
| 161 |  | 
|---|
| 162 | // 指定したデバイスがインストールされているか調査 | 
|---|
| 163 | bool Win32IsDeviceSupported(SECURE_DEVICE *dev) | 
|---|
| 164 | { | 
|---|
| 165 |     HINSTANCE hInst; | 
|---|
| 166 |     // 引数チェック | 
|---|
| 167 |     if (dev == NULL) | 
|---|
| 168 |     { | 
|---|
| 169 |         return false; | 
|---|
| 170 |     } | 
|---|
| 171 |  | 
|---|
| 172 |     // DLL が読み込み可能かチェック | 
|---|
| 173 |     hInst = Win32SecureLoadLibraryEx(dev->ModuleName, DONT_RESOLVE_DLL_REFERENCES); | 
|---|
| 174 |     if (hInst == NULL) | 
|---|
| 175 |     { | 
|---|
| 176 |         return false; | 
|---|
| 177 |     } | 
|---|
| 178 |  | 
|---|
| 179 |     FreeLibrary(hInst); | 
|---|
| 180 |  | 
|---|
| 181 |     return true; | 
|---|
| 182 | } | 
|---|
| 183 |  | 
|---|
| 184 | // デバイスモジュールの読み込み | 
|---|
| 185 | bool Win32LoadSecModule(SECURE *sec) | 
|---|
| 186 | { | 
|---|
| 187 |     SEC_DATA_WIN32 *w; | 
|---|
| 188 |     HINSTANCE hInst; | 
|---|
| 189 |     CK_FUNCTION_LIST_PTR api = NULL; | 
|---|
| 190 |     CK_RV (*get_function_list)(CK_FUNCTION_LIST_PTR_PTR); | 
|---|
| 191 |     // 引数チェック | 
|---|
| 192 |     if (sec == NULL) | 
|---|
| 193 |     { | 
|---|
| 194 |         return false; | 
|---|
| 195 |     } | 
|---|
| 196 |  | 
|---|
| 197 |     if (sec->Dev->Id == 9) | 
|---|
| 198 |     { | 
|---|
| 199 |         char username[MAX_SIZE]; | 
|---|
| 200 |         DWORD size; | 
|---|
| 201 |         // 住基ネットのデバイスドライバでは、Software\JPKI レジストリキーの内容を | 
|---|
| 202 |         // SYSTEM の HKLU でも持っていなければならないので、もし持っていない場合は | 
|---|
| 203 |         // 別のユーザーの値からコピーする | 
|---|
| 204 | //      if (MsRegIsValue(REG_CURRENT_USER, "Software\\JPKI", "Name") == false || | 
|---|
| 205 | //          MsRegIsValue(REG_CURRENT_USER, "Software\\JPKI", "RWType") == false) | 
|---|
| 206 |         size = sizeof(username); | 
|---|
| 207 |         GetUserName(username, &size); | 
|---|
| 208 |         if (StrCmpi(username, "System") == 0) | 
|---|
| 209 |         { | 
|---|
| 210 |             TOKEN_LIST *t = MsRegEnumKey(REG_USERS, NULL); | 
|---|
| 211 |  | 
|---|
| 212 |             if (t != NULL) | 
|---|
| 213 |             { | 
|---|
| 214 |                 UINT i; | 
|---|
| 215 |  | 
|---|
| 216 |                 for (i = 0;i < t->NumTokens;i++) | 
|---|
| 217 |                 { | 
|---|
| 218 |                     char tmp[MAX_PATH]; | 
|---|
| 219 |  | 
|---|
| 220 |                     if (StrCmpi(t->Token[i], ".DEFAULT") != 0 && StrCmpi(t->Token[i], "S-1-5-18") != 0) | 
|---|
| 221 |                     { | 
|---|
| 222 |                         Format(tmp, sizeof(tmp), "%s\\Software\\JPKI", t->Token[i]); | 
|---|
| 223 |  | 
|---|
| 224 |                         if (MsRegIsValue(REG_USERS, tmp, "Name") && MsRegIsValue(REG_USERS, tmp, "RWType")) | 
|---|
| 225 |                         { | 
|---|
| 226 |                             char *name = MsRegReadStr(REG_USERS, tmp, "Name"); | 
|---|
| 227 |                             char *port = MsRegReadStr(REG_USERS, tmp, "Port"); | 
|---|
| 228 |                             UINT type = MsRegReadInt(REG_USERS, tmp, "RWType"); | 
|---|
| 229 |  | 
|---|
| 230 |                             MsRegWriteStr(REG_CURRENT_USER, "Software\\JPKI", "Name", name); | 
|---|
| 231 |                             MsRegWriteStr(REG_CURRENT_USER, "Software\\JPKI", "Port", port); | 
|---|
| 232 |                             MsRegWriteInt(REG_CURRENT_USER, "Software\\JPKI", "RWType", type); | 
|---|
| 233 |  | 
|---|
| 234 |                             Free(name); | 
|---|
| 235 |                             Free(port); | 
|---|
| 236 |                             break; | 
|---|
| 237 |                         } | 
|---|
| 238 |                     } | 
|---|
| 239 |                 } | 
|---|
| 240 |  | 
|---|
| 241 |                 FreeToken(t); | 
|---|
| 242 |             } | 
|---|
| 243 |         } | 
|---|
| 244 |     } | 
|---|
| 245 |  | 
|---|
| 246 |     // ライブラリのロード | 
|---|
| 247 |     hInst = Win32SecureLoadLibraryEx(sec->Dev->ModuleName, 0); | 
|---|
| 248 |     if (hInst == NULL) | 
|---|
| 249 |     { | 
|---|
| 250 |         // 失敗 | 
|---|
| 251 |         return false; | 
|---|
| 252 |     } | 
|---|
| 253 |  | 
|---|
| 254 |     // API の取得 | 
|---|
| 255 |     get_function_list = (CK_RV (*)(CK_FUNCTION_LIST_PTR_PTR)) | 
|---|
| 256 |         GetProcAddress(hInst, "C_GetFunctionList"); | 
|---|
| 257 |  | 
|---|
| 258 |     if (get_function_list == NULL) | 
|---|
| 259 |     { | 
|---|
| 260 |         // 失敗 | 
|---|
| 261 |         FreeLibrary(hInst); | 
|---|
| 262 |         return false; | 
|---|
| 263 |     } | 
|---|
| 264 |  | 
|---|
| 265 |     get_function_list(&api); | 
|---|
| 266 |     if (api == NULL) | 
|---|
| 267 |     { | 
|---|
| 268 |         // 失敗 | 
|---|
| 269 |         FreeLibrary(hInst); | 
|---|
| 270 |         return false; | 
|---|
| 271 |     } | 
|---|
| 272 |  | 
|---|
| 273 |     sec->Data = ZeroMalloc(sizeof(SEC_DATA_WIN32)); | 
|---|
| 274 |     w = sec->Data; | 
|---|
| 275 |  | 
|---|
| 276 |     w->hInst = hInst; | 
|---|
| 277 |     sec->Api = api; | 
|---|
| 278 |  | 
|---|
| 279 |     return true; | 
|---|
| 280 | } | 
|---|
| 281 |  | 
|---|
| 282 | // デバイスモジュールのアンロード | 
|---|
| 283 | void Win32FreeSecModule(SECURE *sec) | 
|---|
| 284 | { | 
|---|
| 285 |     // 引数チェック | 
|---|
| 286 |     if (sec == NULL) | 
|---|
| 287 |     { | 
|---|
| 288 |         return; | 
|---|
| 289 |     } | 
|---|
| 290 |     if (sec->Data == NULL) | 
|---|
| 291 |     { | 
|---|
| 292 |         return; | 
|---|
| 293 |     } | 
|---|
| 294 |  | 
|---|
| 295 |     // アンロード | 
|---|
| 296 |     FreeLibrary(sec->Data->hInst); | 
|---|
| 297 |     Free(sec->Data); | 
|---|
| 298 |  | 
|---|
| 299 |     sec->Data = NULL; | 
|---|
| 300 | } | 
|---|
| 301 |  | 
|---|
| 302 | #endif  // OS_WIN32 | 
|---|
| 303 |  | 
|---|
| 304 |  | 
|---|
| 305 | // 指定されたデバイスが JPKI かどうか | 
|---|
| 306 | bool IsJPKI(bool id) | 
|---|
| 307 | { | 
|---|
| 308 |     if (id == 9 || id == 13) | 
|---|
| 309 |     { | 
|---|
| 310 |         return true; | 
|---|
| 311 |     } | 
|---|
| 312 |  | 
|---|
| 313 |     return false; | 
|---|
| 314 | } | 
|---|
| 315 |  | 
|---|
| 316 | // セキュアデバイスの秘密鍵を名前を指定して署名 | 
|---|
| 317 | bool SignSec(SECURE *sec, char *name, void *dst, void *src, UINT size) | 
|---|
| 318 | { | 
|---|
| 319 |     SEC_OBJ *obj; | 
|---|
| 320 |     UINT ret; | 
|---|
| 321 |     // 引数チェック | 
|---|
| 322 |     if (sec == NULL) | 
|---|
| 323 |     { | 
|---|
| 324 |         return false; | 
|---|
| 325 |     } | 
|---|
| 326 |     if (name == NULL || dst == NULL || src == NULL) | 
|---|
| 327 |     { | 
|---|
| 328 |         sec->Error = SEC_ERROR_BAD_PARAMETER; | 
|---|
| 329 |         return false; | 
|---|
| 330 |     } | 
|---|
| 331 |  | 
|---|
| 332 |     obj = FindSecObject(sec, name, SEC_K); | 
|---|
| 333 |     if (obj == NULL) | 
|---|
| 334 |     { | 
|---|
| 335 |         return false; | 
|---|
| 336 |     } | 
|---|
| 337 |  | 
|---|
| 338 |     ret = SignSecByObject(sec, obj, dst, src, size); | 
|---|
| 339 |  | 
|---|
| 340 |     FreeSecObject(obj); | 
|---|
| 341 |  | 
|---|
| 342 |     return ret; | 
|---|
| 343 | } | 
|---|
| 344 |  | 
|---|
| 345 | // セキュアデバイスの秘密鍵で署名 | 
|---|
| 346 | bool SignSecByObject(SECURE *sec, SEC_OBJ *obj, void *dst, void *src, UINT size) | 
|---|
| 347 | { | 
|---|
| 348 |     CK_MECHANISM mechanism = {CKM_RSA_PKCS, NULL, 0}; | 
|---|
| 349 |     UINT ret; | 
|---|
| 350 |     UCHAR hash[SIGN_HASH_SIZE]; | 
|---|
| 351 |     // 引数チェック | 
|---|
| 352 |     if (sec == NULL) | 
|---|
| 353 |     { | 
|---|
| 354 |         return false; | 
|---|
| 355 |     } | 
|---|
| 356 |     if (obj == NULL || dst == NULL || src == NULL) | 
|---|
| 357 |     { | 
|---|
| 358 |         sec->Error = SEC_ERROR_BAD_PARAMETER; | 
|---|
| 359 |         return false; | 
|---|
| 360 |     } | 
|---|
| 361 |     if (sec->SessionCreated == false) | 
|---|
| 362 |     { | 
|---|
| 363 |         sec->Error = SEC_ERROR_NO_SESSION; | 
|---|
| 364 |         return false; | 
|---|
| 365 |     } | 
|---|
| 366 |     if (sec->LoginFlag == false && obj->Private) | 
|---|
| 367 |     { | 
|---|
| 368 |         sec->Error = SEC_ERROR_NOT_LOGIN; | 
|---|
| 369 |         return false; | 
|---|
| 370 |     } | 
|---|
| 371 |     if (obj->Type != SEC_K) | 
|---|
| 372 |     { | 
|---|
| 373 |         sec->Error = SEC_ERROR_BAD_PARAMETER; | 
|---|
| 374 |         return false; | 
|---|
| 375 |     } | 
|---|
| 376 |  | 
|---|
| 377 |     // ハッシュ | 
|---|
| 378 |     HashForSign(hash, sizeof(hash), src, size); | 
|---|
| 379 |  | 
|---|
| 380 |     // 署名初期化 | 
|---|
| 381 |     ret = sec->Api->C_SignInit(sec->SessionId, &mechanism, obj->Object); | 
|---|
| 382 |     if (ret != CKR_OK) | 
|---|
| 383 |     { | 
|---|
| 384 |         // 失敗 | 
|---|
| 385 |         sec->Error = SEC_ERROR_HARDWARE_ERROR; | 
|---|
| 386 |         Debug("C_SignInit Error: 0x%x\n", ret); | 
|---|
| 387 |         return false; | 
|---|
| 388 |     } | 
|---|
| 389 |  | 
|---|
| 390 |     // 署名実行 | 
|---|
| 391 |     size = 128; | 
|---|
| 392 |     ret = sec->Api->C_Sign(sec->SessionId, hash, sizeof(hash), dst, &size); | 
|---|
| 393 |     if (ret != CKR_OK || size != 128) | 
|---|
| 394 |     { | 
|---|
| 395 |         // 失敗 | 
|---|
| 396 |         sec->Error = SEC_ERROR_HARDWARE_ERROR; | 
|---|
| 397 |         Debug("C_Sign Error: 0x%x\n", ret); | 
|---|
| 398 |         return false; | 
|---|
| 399 |     } | 
|---|
| 400 |  | 
|---|
| 401 |     return true; | 
|---|
| 402 | } | 
|---|
| 403 |  | 
|---|
| 404 | // PIN コードの変更 | 
|---|
| 405 | bool ChangePin(SECURE *sec, char *old_pin, char *new_pin) | 
|---|
| 406 | { | 
|---|
| 407 |     // 引数チェック | 
|---|
| 408 |     if (sec == NULL || old_pin == NULL || new_pin == NULL) | 
|---|
| 409 |     { | 
|---|
| 410 |         return false; | 
|---|
| 411 |     } | 
|---|
| 412 |     if (sec->SessionCreated == false) | 
|---|
| 413 |     { | 
|---|
| 414 |         sec->Error = SEC_ERROR_NO_SESSION; | 
|---|
| 415 |         return false; | 
|---|
| 416 |     } | 
|---|
| 417 |     if (sec->LoginFlag == false) | 
|---|
| 418 |     { | 
|---|
| 419 |         sec->Error = SEC_ERROR_NOT_LOGIN; | 
|---|
| 420 |         return false; | 
|---|
| 421 |     } | 
|---|
| 422 |     if (sec->IsReadOnly) | 
|---|
| 423 |     { | 
|---|
| 424 |         sec->Error = SEC_ERROR_OPEN_SESSION; | 
|---|
| 425 |         return false; | 
|---|
| 426 |     } | 
|---|
| 427 |  | 
|---|
| 428 |     // PIN 変更 | 
|---|
| 429 |     if (sec->Api->C_SetPIN(sec->SessionId, old_pin, StrLen(old_pin), | 
|---|
| 430 |         new_pin, StrLen(new_pin)) != CKR_OK) | 
|---|
| 431 |     { | 
|---|
| 432 |         return false; | 
|---|
| 433 |     } | 
|---|
| 434 |  | 
|---|
| 435 |     return true; | 
|---|
| 436 | } | 
|---|
| 437 |  | 
|---|
| 438 | // 秘密鍵オブジェクトの書き込み | 
|---|
| 439 | bool WriteSecKey(SECURE *sec, bool private_obj, char *name, K *k) | 
|---|
| 440 | { | 
|---|
| 441 |     UINT key_type = CKK_RSA; | 
|---|
| 442 |     CK_BBOOL b_true = true, b_false = false, b_private_obj = private_obj; | 
|---|
| 443 |     UINT obj_class = CKO_PRIVATE_KEY; | 
|---|
| 444 |     UINT object; | 
|---|
| 445 |     UINT ret; | 
|---|
| 446 |     BUF *b; | 
|---|
| 447 |     RSA *rsa; | 
|---|
| 448 |     UCHAR modules[MAX_SIZE], pub[MAX_SIZE], pri[MAX_SIZE], prime1[MAX_SIZE], prime2[MAX_SIZE]; | 
|---|
| 449 |     CK_ATTRIBUTE a[] = | 
|---|
| 450 |     { | 
|---|
| 451 |         {CKA_MODULUS,           modules,        0},     // 0 | 
|---|
| 452 |         {CKA_PUBLIC_EXPONENT,   pub,            0},     // 1 | 
|---|
| 453 |         {CKA_PRIVATE_EXPONENT,  pri,            0},     // 2 | 
|---|
| 454 |         {CKA_PRIME_1,           prime1,         0},     // 3 | 
|---|
| 455 |         {CKA_PRIME_2,           prime2,         0},     // 4 | 
|---|
| 456 |         {CKA_CLASS,             &obj_class,     sizeof(obj_class)}, | 
|---|
| 457 |         {CKA_TOKEN,             &b_true,        sizeof(b_true)}, | 
|---|
| 458 |         {CKA_PRIVATE,           &b_private_obj, sizeof(b_private_obj)}, | 
|---|
| 459 |         {CKA_LABEL,             name,           StrLen(name)}, | 
|---|
| 460 |         {CKA_KEY_TYPE,          &key_type,      sizeof(key_type)}, | 
|---|
| 461 |         {CKA_DERIVE,            &b_false,       sizeof(b_false)}, | 
|---|
| 462 |         {CKA_SUBJECT,           name,           StrLen(name)}, | 
|---|
| 463 |         {CKA_SENSITIVE,         &b_true,        sizeof(b_true)}, | 
|---|
| 464 |         {CKA_DECRYPT,           &b_true,        sizeof(b_true)}, | 
|---|
| 465 |         {CKA_SIGN,              &b_true,        sizeof(b_true)}, | 
|---|
| 466 |         {CKA_SIGN_RECOVER,      &b_false,       sizeof(b_false)}, | 
|---|
| 467 |         {CKA_EXTRACTABLE,       &b_false,       sizeof(b_false)}, | 
|---|
| 468 |         {CKA_MODIFIABLE,        &b_false,       sizeof(b_false)}, | 
|---|
| 469 |     }; | 
|---|
| 470 |     // 引数チェック | 
|---|
| 471 |     if (sec == NULL) | 
|---|
| 472 |     { | 
|---|
| 473 |         return false; | 
|---|
| 474 |     } | 
|---|
| 475 |     if (name == NULL || k == NULL || k->private_key == false) | 
|---|
| 476 |     { | 
|---|
| 477 |         sec->Error = SEC_ERROR_BAD_PARAMETER; | 
|---|
| 478 |         return false; | 
|---|
| 479 |     } | 
|---|
| 480 |     if (sec->SessionCreated == false) | 
|---|
| 481 |     { | 
|---|
| 482 |         sec->Error = SEC_ERROR_NO_SESSION; | 
|---|
| 483 |         return false; | 
|---|
| 484 |     } | 
|---|
| 485 |     if (sec->LoginFlag == false && private_obj) | 
|---|
| 486 |     { | 
|---|
| 487 |         sec->Error = SEC_ERROR_NOT_LOGIN; | 
|---|
| 488 |         return false; | 
|---|
| 489 |     } | 
|---|
| 490 |  | 
|---|
| 491 |     // 数値データ生成 | 
|---|
| 492 |     rsa = k->pkey->pkey.rsa; | 
|---|
| 493 |     if (rsa == NULL) | 
|---|
| 494 |     { | 
|---|
| 495 |         sec->Error = SEC_ERROR_BAD_PARAMETER; | 
|---|
| 496 |         return false; | 
|---|
| 497 |     } | 
|---|
| 498 |     b = BigNumToBuf(rsa->n); | 
|---|
| 499 |     ReadBuf(b, modules, sizeof(modules)); | 
|---|
| 500 |     A_SIZE(a, 0) = b->Size; | 
|---|
| 501 |     FreeBuf(b); | 
|---|
| 502 |  | 
|---|
| 503 |     b = BigNumToBuf(rsa->e); | 
|---|
| 504 |     ReadBuf(b, pub, sizeof(pub)); | 
|---|
| 505 |     A_SIZE(a, 1) = b->Size; | 
|---|
| 506 |     FreeBuf(b); | 
|---|
| 507 |  | 
|---|
| 508 |     b = BigNumToBuf(rsa->d); | 
|---|
| 509 |     ReadBuf(b, pri, sizeof(pri)); | 
|---|
| 510 |     A_SIZE(a, 2) = b->Size; | 
|---|
| 511 |     FreeBuf(b); | 
|---|
| 512 |  | 
|---|
| 513 |     b = BigNumToBuf(rsa->p); | 
|---|
| 514 |     ReadBuf(b, prime1, sizeof(prime1)); | 
|---|
| 515 |     A_SIZE(a, 3) = b->Size; | 
|---|
| 516 |     FreeBuf(b); | 
|---|
| 517 |  | 
|---|
| 518 |     b = BigNumToBuf(rsa->q); | 
|---|
| 519 |     ReadBuf(b, prime2, sizeof(prime2)); | 
|---|
| 520 |     A_SIZE(a, 4) = b->Size; | 
|---|
| 521 |     FreeBuf(b); | 
|---|
| 522 |  | 
|---|
| 523 |     // 古い鍵があれば削除 | 
|---|
| 524 |     if (CheckSecObject(sec, name, SEC_K)) | 
|---|
| 525 |     { | 
|---|
| 526 |         DeleteSecKey(sec, name); | 
|---|
| 527 |     } | 
|---|
| 528 |  | 
|---|
| 529 |     // 作成 | 
|---|
| 530 |     if ((ret = sec->Api->C_CreateObject(sec->SessionId, a, sizeof(a) / sizeof(a[0]), &object)) != CKR_OK) | 
|---|
| 531 |     { | 
|---|
| 532 |         // 失敗 | 
|---|
| 533 |         sec->Error = SEC_ERROR_HARDWARE_ERROR; | 
|---|
| 534 |         Debug("ret: 0x%x\n", ret); | 
|---|
| 535 |         return false; | 
|---|
| 536 |     } | 
|---|
| 537 |  | 
|---|
| 538 |     // キャッシュ消去 | 
|---|
| 539 |     EraseEnumSecObjectCache(sec); | 
|---|
| 540 |  | 
|---|
| 541 |     return true; | 
|---|
| 542 | } | 
|---|
| 543 |  | 
|---|
| 544 | // 証明書オブジェクトを名前を指定して読み込み | 
|---|
| 545 | X *ReadSecCert(SECURE *sec, char *name) | 
|---|
| 546 | { | 
|---|
| 547 |     SEC_OBJ *obj; | 
|---|
| 548 |     X *x; | 
|---|
| 549 |     // 引数チェック | 
|---|
| 550 |     if (sec == NULL) | 
|---|
| 551 |     { | 
|---|
| 552 |         return false; | 
|---|
| 553 |     } | 
|---|
| 554 |     if (sec->SessionCreated == false) | 
|---|
| 555 |     { | 
|---|
| 556 |         sec->Error = SEC_ERROR_NO_SESSION; | 
|---|
| 557 |         return false; | 
|---|
| 558 |     } | 
|---|
| 559 |  | 
|---|
| 560 |     // 検索 | 
|---|
| 561 |     obj = FindSecObject(sec, name, SEC_X); | 
|---|
| 562 |     if (obj == NULL) | 
|---|
| 563 |     { | 
|---|
| 564 |         return false; | 
|---|
| 565 |     } | 
|---|
| 566 |  | 
|---|
| 567 |     // 取得 | 
|---|
| 568 |     x = ReadSecCertFromObject(sec, obj); | 
|---|
| 569 |  | 
|---|
| 570 |     FreeSecObject(obj); | 
|---|
| 571 |  | 
|---|
| 572 |     return x; | 
|---|
| 573 | } | 
|---|
| 574 |  | 
|---|
| 575 | // 証明書オブジェクトの読み込み | 
|---|
| 576 | X *ReadSecCertFromObject(SECURE *sec, SEC_OBJ *obj) | 
|---|
| 577 | { | 
|---|
| 578 |     UINT size; | 
|---|
| 579 |     X *x; | 
|---|
| 580 |     UCHAR value[4096]; | 
|---|
| 581 |     BUF *b; | 
|---|
| 582 |     CK_ATTRIBUTE get[] = | 
|---|
| 583 |     { | 
|---|
| 584 |         {CKA_VALUE,     value,      sizeof(value)}, | 
|---|
| 585 |     }; | 
|---|
| 586 |     // 引数チェック | 
|---|
| 587 |     if (sec == NULL) | 
|---|
| 588 |     { | 
|---|
| 589 |         return false; | 
|---|
| 590 |     } | 
|---|
| 591 |     if (sec->SessionCreated == false) | 
|---|
| 592 |     { | 
|---|
| 593 |         sec->Error = SEC_ERROR_NO_SESSION; | 
|---|
| 594 |         return false; | 
|---|
| 595 |     } | 
|---|
| 596 |     if (sec->LoginFlag == false && obj->Private) | 
|---|
| 597 |     { | 
|---|
| 598 |         sec->Error = SEC_ERROR_NOT_LOGIN; | 
|---|
| 599 |         return false; | 
|---|
| 600 |     } | 
|---|
| 601 |     if (obj->Type != SEC_X) | 
|---|
| 602 |     { | 
|---|
| 603 |         sec->Error = SEC_ERROR_BAD_PARAMETER; | 
|---|
| 604 |         return false; | 
|---|
| 605 |     } | 
|---|
| 606 |  | 
|---|
| 607 |     // 取得 | 
|---|
| 608 |     if (sec->Api->C_GetAttributeValue( | 
|---|
| 609 |         sec->SessionId, obj->Object, get, sizeof(get) / sizeof(get[0])) != CKR_OK) | 
|---|
| 610 |     { | 
|---|
| 611 |         sec->Error = SEC_ERROR_HARDWARE_ERROR; | 
|---|
| 612 |         return 0; | 
|---|
| 613 |     } | 
|---|
| 614 |  | 
|---|
| 615 |     size = A_SIZE(get, 0); | 
|---|
| 616 |  | 
|---|
| 617 |     // 変換 | 
|---|
| 618 |     b = NewBuf(); | 
|---|
| 619 |     WriteBuf(b, value, size); | 
|---|
| 620 |     SeekBuf(b, 0, 0); | 
|---|
| 621 |  | 
|---|
| 622 |     x = BufToX(b, false); | 
|---|
| 623 |     if (x == NULL) | 
|---|
| 624 |     { | 
|---|
| 625 |         sec->Error = SEC_ERROR_INVALID_CERT; | 
|---|
| 626 |     } | 
|---|
| 627 |  | 
|---|
| 628 |     FreeBuf(b); | 
|---|
| 629 |  | 
|---|
| 630 |     return x; | 
|---|
| 631 | } | 
|---|
| 632 |  | 
|---|
| 633 | // 証明書オブジェクトの書き込み | 
|---|
| 634 | bool WriteSecCert(SECURE *sec, bool private_obj, char *name, X *x) | 
|---|
| 635 | { | 
|---|
| 636 |     UINT obj_class = CKO_CERTIFICATE; | 
|---|
| 637 |     CK_BBOOL b_true = true, b_false = false, b_private_obj = private_obj; | 
|---|
| 638 |     UINT cert_type = CKC_X_509; | 
|---|
| 639 |     CK_DATE start_date, end_date; | 
|---|
| 640 |     UCHAR subject[MAX_SIZE]; | 
|---|
| 641 |     UCHAR issuer[MAX_SIZE]; | 
|---|
| 642 |     wchar_t w_subject[MAX_SIZE]; | 
|---|
| 643 |     wchar_t w_issuer[MAX_SIZE]; | 
|---|
| 644 |     UCHAR serial_number[MAX_SIZE]; | 
|---|
| 645 |     UCHAR value[4096]; | 
|---|
| 646 |     UINT ret; | 
|---|
| 647 |     BUF *b; | 
|---|
| 648 |     UINT object; | 
|---|
| 649 |     CK_ATTRIBUTE a[] = | 
|---|
| 650 |     { | 
|---|
| 651 |         {CKA_SUBJECT,           subject,        0},         // 0 | 
|---|
| 652 |         {CKA_ISSUER,            issuer,         0},         // 1 | 
|---|
| 653 |         {CKA_SERIAL_NUMBER,     serial_number,  0},         // 2 | 
|---|
| 654 |         {CKA_VALUE,             value,          0},         // 3 | 
|---|
| 655 |         {CKA_CLASS,             &obj_class,     sizeof(obj_class)}, | 
|---|
| 656 |         {CKA_TOKEN,             &b_true,        sizeof(b_true)}, | 
|---|
| 657 |         {CKA_PRIVATE,           &b_private_obj, sizeof(b_private_obj)}, | 
|---|
| 658 |         {CKA_LABEL,             name,           StrLen(name)}, | 
|---|
| 659 |         {CKA_CERTIFICATE_TYPE,  &cert_type,     sizeof(cert_type)}, | 
|---|
| 660 | #if 0       // 失敗するトークンがあるのでこれは使わない | 
|---|
| 661 |         {CKA_START_DATE,        &start_date,    sizeof(start_date)}, | 
|---|
| 662 |         {CKA_END_DATE,          &end_date,      sizeof(end_date)}, | 
|---|
| 663 | #endif | 
|---|
| 664 |     }; | 
|---|
| 665 |     // 引数チェック | 
|---|
| 666 |     if (sec == NULL) | 
|---|
| 667 |     { | 
|---|
| 668 |         return false; | 
|---|
| 669 |     } | 
|---|
| 670 |     if (name == NULL) | 
|---|
| 671 |     { | 
|---|
| 672 |         sec->Error = SEC_ERROR_BAD_PARAMETER; | 
|---|
| 673 |         return false; | 
|---|
| 674 |     } | 
|---|
| 675 |     if (sec->SessionCreated == false) | 
|---|
| 676 |     { | 
|---|
| 677 |         sec->Error = SEC_ERROR_NO_SESSION; | 
|---|
| 678 |         return false; | 
|---|
| 679 |     } | 
|---|
| 680 |     if (sec->LoginFlag == false && private_obj) | 
|---|
| 681 |     { | 
|---|
| 682 |         sec->Error = SEC_ERROR_NOT_LOGIN; | 
|---|
| 683 |         return false; | 
|---|
| 684 |     } | 
|---|
| 685 |  | 
|---|
| 686 |     // 証明書をバッファにコピー | 
|---|
| 687 |     b = XToBuf(x, false); | 
|---|
| 688 |     if (b == NULL) | 
|---|
| 689 |     { | 
|---|
| 690 |         sec->Error = SEC_ERROR_INVALID_CERT; | 
|---|
| 691 |         return false; | 
|---|
| 692 |     } | 
|---|
| 693 |     if (b->Size > sizeof(value)) | 
|---|
| 694 |     { | 
|---|
| 695 |         // サイズが大きすぎる | 
|---|
| 696 |         FreeBuf(b); | 
|---|
| 697 |         sec->Error = SEC_ERROR_DATA_TOO_BIG; | 
|---|
| 698 |         return false; | 
|---|
| 699 |     } | 
|---|
| 700 |     Copy(value, b->Buf, b->Size); | 
|---|
| 701 |     A_SIZE(a, 3) = b->Size; | 
|---|
| 702 |     FreeBuf(b); | 
|---|
| 703 |  | 
|---|
| 704 |     // Subject と Issuer を UTF-8 にエンコードして格納 | 
|---|
| 705 |     GetPrintNameFromName(w_subject, sizeof(w_subject), x->subject_name); | 
|---|
| 706 |     UniToUtf8(subject, sizeof(subject), w_subject); | 
|---|
| 707 |     A_SIZE(a, 0) = StrLen(subject); | 
|---|
| 708 |     if (x->root_cert == false) | 
|---|
| 709 |     { | 
|---|
| 710 |         GetPrintNameFromName(w_issuer, sizeof(w_issuer), x->issuer_name); | 
|---|
| 711 |         UniToUtf8(issuer, sizeof(issuer), w_issuer); | 
|---|
| 712 |         A_SIZE(a, 1) = StrLen(issuer); | 
|---|
| 713 |     } | 
|---|
| 714 |  | 
|---|
| 715 |     // シリアル番号をコピー | 
|---|
| 716 |     Copy(serial_number, x->serial->data, MIN(x->serial->size, sizeof(serial_number))); | 
|---|
| 717 |     A_SIZE(a, 2) = MIN(x->serial->size, sizeof(serial_number)); | 
|---|
| 718 |  | 
|---|
| 719 |     // 有効期限情報 | 
|---|
| 720 |     UINT64ToCkDate(&start_date, SystemToLocal64(x->notBefore)); | 
|---|
| 721 |     UINT64ToCkDate(&end_date, SystemToLocal64(x->notAfter)); | 
|---|
| 722 |  | 
|---|
| 723 |     // 同一の名前のオブジェクトがあれば削除 | 
|---|
| 724 |     if (CheckSecObject(sec, name, SEC_X)) | 
|---|
| 725 |     { | 
|---|
| 726 |         DeleteSecCert(sec, name); | 
|---|
| 727 |     } | 
|---|
| 728 |  | 
|---|
| 729 |     // 作成 | 
|---|
| 730 |     if ((ret = sec->Api->C_CreateObject(sec->SessionId, a, sizeof(a) / sizeof(a[0]), &object)) != CKR_OK) | 
|---|
| 731 |     { | 
|---|
| 732 |         // 失敗 | 
|---|
| 733 |         sec->Error = SEC_ERROR_HARDWARE_ERROR; | 
|---|
| 734 |         Debug("Error: 0x%02x\n", ret); | 
|---|
| 735 |         return false; | 
|---|
| 736 |     } | 
|---|
| 737 |  | 
|---|
| 738 |     // キャッシュ消去 | 
|---|
| 739 |     EraseEnumSecObjectCache(sec); | 
|---|
| 740 |  | 
|---|
| 741 |     return true; | 
|---|
| 742 | } | 
|---|
| 743 |  | 
|---|
| 744 | // 秘密鍵オブジェクトの削除 | 
|---|
| 745 | bool DeleteSecKey(SECURE *sec, char *name) | 
|---|
| 746 | { | 
|---|
| 747 |     return DeleteSecObjectByName(sec, name, SEC_K); | 
|---|
| 748 | } | 
|---|
| 749 |  | 
|---|
| 750 | // 証明書オブジェクトの削除 | 
|---|
| 751 | bool DeleteSecCert(SECURE *sec, char *name) | 
|---|
| 752 | { | 
|---|
| 753 |     return DeleteSecObjectByName(sec, name, SEC_X); | 
|---|
| 754 | } | 
|---|
| 755 |  | 
|---|
| 756 | // CK_DATE を 64 bit 時刻に変換 | 
|---|
| 757 | UINT64 CkDateToUINT64(struct CK_DATE *ck_date) | 
|---|
| 758 | { | 
|---|
| 759 |     SYSTEMTIME st; | 
|---|
| 760 |     char year[32], month[32], day[32]; | 
|---|
| 761 |     // 引数チェック | 
|---|
| 762 |     if (ck_date == NULL) | 
|---|
| 763 |     { | 
|---|
| 764 |         return 0; | 
|---|
| 765 |     } | 
|---|
| 766 |  | 
|---|
| 767 |     Zero(year, sizeof(year)); | 
|---|
| 768 |     Zero(month, sizeof(month)); | 
|---|
| 769 |     Zero(day, sizeof(day)); | 
|---|
| 770 |  | 
|---|
| 771 |     Copy(year, ck_date->year, 4); | 
|---|
| 772 |     Copy(month, ck_date->month, 2); | 
|---|
| 773 |     Copy(day, ck_date->day, 2); | 
|---|
| 774 |  | 
|---|
| 775 |     st.wYear = ToInt(year); | 
|---|
| 776 |     st.wMonth = ToInt(month); | 
|---|
| 777 |     st.wDay = ToInt(day); | 
|---|
| 778 |  | 
|---|
| 779 |     return SystemToUINT64(&st); | 
|---|
| 780 | } | 
|---|
| 781 |  | 
|---|
| 782 | // 64 bit 時刻を CK_DATE に変換 | 
|---|
| 783 | void UINT64ToCkDate(void *p_ck_date, UINT64 time64) | 
|---|
| 784 | { | 
|---|
| 785 |     SYSTEMTIME st; | 
|---|
| 786 |     char year[32], month[32], day[32]; | 
|---|
| 787 |     struct CK_DATE *ck_date = (CK_DATE *)p_ck_date; | 
|---|
| 788 |     // 引数チェック | 
|---|
| 789 |     if (ck_date == NULL) | 
|---|
| 790 |     { | 
|---|
| 791 |         return; | 
|---|
| 792 |     } | 
|---|
| 793 |  | 
|---|
| 794 |     UINT64ToSystem(&st, time64); | 
|---|
| 795 |  | 
|---|
| 796 |     Format(year, sizeof(year), "%04u", st.wYear); | 
|---|
| 797 |     Format(month, sizeof(month), "%04u", st.wMonth); | 
|---|
| 798 |     Format(day, sizeof(day), "%04u", st.wDay); | 
|---|
| 799 |  | 
|---|
| 800 |     Zero(ck_date, sizeof(CK_DATE)); | 
|---|
| 801 |  | 
|---|
| 802 |     Copy(ck_date->year, year, 4); | 
|---|
| 803 |     Copy(ck_date->month, month, 2); | 
|---|
| 804 |     Copy(ck_date->day, day, 2); | 
|---|
| 805 | } | 
|---|
| 806 |  | 
|---|
| 807 | // オブジェクトを名前で指定して削除 | 
|---|
| 808 | bool DeleteSecObjectByName(SECURE *sec, char *name, UINT type) | 
|---|
| 809 | { | 
|---|
| 810 |     bool ret; | 
|---|
| 811 |     SEC_OBJ *obj; | 
|---|
| 812 |     // 引数チェック | 
|---|
| 813 |     if (sec == NULL) | 
|---|
| 814 |     { | 
|---|
| 815 |         return false; | 
|---|
| 816 |     } | 
|---|
| 817 |     if (name == NULL) | 
|---|
| 818 |     { | 
|---|
| 819 |         sec->Error = SEC_ERROR_BAD_PARAMETER; | 
|---|
| 820 |         return false; | 
|---|
| 821 |     } | 
|---|
| 822 |     if (sec->SessionCreated == false) | 
|---|
| 823 |     { | 
|---|
| 824 |         sec->Error = SEC_ERROR_NO_SESSION; | 
|---|
| 825 |         return false; | 
|---|
| 826 |     } | 
|---|
| 827 |  | 
|---|
| 828 |     // オブジェクト取得 | 
|---|
| 829 |     obj = FindSecObject(sec, name, type); | 
|---|
| 830 |     if (obj == NULL) | 
|---|
| 831 |     { | 
|---|
| 832 |         // 失敗 | 
|---|
| 833 |         return false; | 
|---|
| 834 |     } | 
|---|
| 835 |  | 
|---|
| 836 |     // オブジェクト削除 | 
|---|
| 837 |     ret = DeleteSecObject(sec, obj); | 
|---|
| 838 |  | 
|---|
| 839 |     // メモリ解放 | 
|---|
| 840 |     FreeSecObject(obj); | 
|---|
| 841 |  | 
|---|
| 842 |     return ret; | 
|---|
| 843 | } | 
|---|
| 844 |  | 
|---|
| 845 | // データの削除 | 
|---|
| 846 | bool DeleteSecData(SECURE *sec, char *name) | 
|---|
| 847 | { | 
|---|
| 848 |     // 引数チェック | 
|---|
| 849 |     if (sec == NULL) | 
|---|
| 850 |     { | 
|---|
| 851 |         return false; | 
|---|
| 852 |     } | 
|---|
| 853 |     if (name == NULL) | 
|---|
| 854 |     { | 
|---|
| 855 |         sec->Error = SEC_ERROR_BAD_PARAMETER; | 
|---|
| 856 |         return false; | 
|---|
| 857 |     } | 
|---|
| 858 |  | 
|---|
| 859 |     return DeleteSecObjectByName(sec, name, SEC_DATA); | 
|---|
| 860 | } | 
|---|
| 861 |  | 
|---|
| 862 | // セキュアオブジェクトの削除 | 
|---|
| 863 | bool DeleteSecObject(SECURE *sec, SEC_OBJ *obj) | 
|---|
| 864 | { | 
|---|
| 865 |     // 引数チェック | 
|---|
| 866 |     if (sec == NULL) | 
|---|
| 867 |     { | 
|---|
| 868 |         return false; | 
|---|
| 869 |     } | 
|---|
| 870 |     if (obj == NULL) | 
|---|
| 871 |     { | 
|---|
| 872 |         sec->Error = SEC_ERROR_BAD_PARAMETER; | 
|---|
| 873 |         return false; | 
|---|
| 874 |     } | 
|---|
| 875 |     if (sec->SessionCreated == false) | 
|---|
| 876 |     { | 
|---|
| 877 |         sec->Error = SEC_ERROR_NO_SESSION; | 
|---|
| 878 |         return false; | 
|---|
| 879 |     } | 
|---|
| 880 |     if (sec->LoginFlag == false && obj->Private) | 
|---|
| 881 |     { | 
|---|
| 882 |         sec->Error = SEC_ERROR_NOT_LOGIN; | 
|---|
| 883 |         return false; | 
|---|
| 884 |     } | 
|---|
| 885 |  | 
|---|
| 886 |     // オブジェクト消去 | 
|---|
| 887 |     if (sec->Api->C_DestroyObject(sec->SessionId, obj->Object) != CKR_OK) | 
|---|
| 888 |     { | 
|---|
| 889 |         sec->Error = SEC_ERROR_HARDWARE_ERROR; | 
|---|
| 890 |         return false; | 
|---|
| 891 |     } | 
|---|
| 892 |  | 
|---|
| 893 |     // キャッシュ消去 | 
|---|
| 894 |     DeleteSecObjFromEnumCache(sec, obj->Name, obj->Type); | 
|---|
| 895 |  | 
|---|
| 896 |     return true; | 
|---|
| 897 | } | 
|---|
| 898 |  | 
|---|
| 899 | // キャッシュから指定した名前のオブジェクトを削除する | 
|---|
| 900 | void DeleteSecObjFromEnumCache(SECURE *sec, char *name, UINT type) | 
|---|
| 901 | { | 
|---|
| 902 |     UINT i; | 
|---|
| 903 |     // 引数チェック | 
|---|
| 904 |     if (sec == NULL || name == NULL || sec->EnumCache == NULL) | 
|---|
| 905 |     { | 
|---|
| 906 |         return; | 
|---|
| 907 |     } | 
|---|
| 908 |  | 
|---|
| 909 |     for (i = 0;i < LIST_NUM(sec->EnumCache);i++) | 
|---|
| 910 |     { | 
|---|
| 911 |         SEC_OBJ *obj = LIST_DATA(sec->EnumCache, i); | 
|---|
| 912 |  | 
|---|
| 913 |         if (StrCmpi(obj->Name, name) == 0) | 
|---|
| 914 |         { | 
|---|
| 915 |             if (obj->Type == type) | 
|---|
| 916 |             { | 
|---|
| 917 |                 Delete(sec->EnumCache, obj); | 
|---|
| 918 |                 FreeSecObject(obj); | 
|---|
| 919 |                 break; | 
|---|
| 920 |             } | 
|---|
| 921 |         } | 
|---|
| 922 |     } | 
|---|
| 923 | } | 
|---|
| 924 |  | 
|---|
| 925 | // セキュアオブジェクトを名前で検索して読み込む | 
|---|
| 926 | int ReadSecData(SECURE *sec, char *name, void *data, UINT size) | 
|---|
| 927 | { | 
|---|
| 928 |     UINT ret = 0; | 
|---|
| 929 |     SEC_OBJ *obj; | 
|---|
| 930 |     // 引数チェック | 
|---|
| 931 |     if (sec == NULL || name == NULL || data == NULL) | 
|---|
| 932 |     { | 
|---|
| 933 |         return 0; | 
|---|
| 934 |     } | 
|---|
| 935 |     if (sec->SessionCreated == false) | 
|---|
| 936 |     { | 
|---|
| 937 |         sec->Error = SEC_ERROR_NO_SESSION; | 
|---|
| 938 |         return 0; | 
|---|
| 939 |     } | 
|---|
| 940 |  | 
|---|
| 941 |     // 読み込み | 
|---|
| 942 |     obj = FindSecObject(sec, name, SEC_DATA); | 
|---|
| 943 |     if (obj == NULL) | 
|---|
| 944 |     { | 
|---|
| 945 |         // 見つからない | 
|---|
| 946 |         return 0; | 
|---|
| 947 |     } | 
|---|
| 948 |  | 
|---|
| 949 |     // 読み込む | 
|---|
| 950 |     ret = ReadSecDataFromObject(sec, obj, data, size); | 
|---|
| 951 |  | 
|---|
| 952 |     FreeSecObject(obj); | 
|---|
| 953 |  | 
|---|
| 954 |     return ret; | 
|---|
| 955 | } | 
|---|
| 956 |  | 
|---|
| 957 | // キャッシュ消去 | 
|---|
| 958 | void EraseEnumSecObjectCache(SECURE *sec) | 
|---|
| 959 | { | 
|---|
| 960 |     // 引数チェック | 
|---|
| 961 |     if (sec == NULL || sec->EnumCache == NULL) | 
|---|
| 962 |     { | 
|---|
| 963 |         return; | 
|---|
| 964 |     } | 
|---|
| 965 |  | 
|---|
| 966 |     FreeEnumSecObject(sec->EnumCache); | 
|---|
| 967 |     sec->EnumCache = NULL; | 
|---|
| 968 | } | 
|---|
| 969 |  | 
|---|
| 970 | // セキュアオブジェクトの存在をチェックする | 
|---|
| 971 | bool CheckSecObject(SECURE *sec, char *name, UINT type) | 
|---|
| 972 | { | 
|---|
| 973 |     SEC_OBJ *obj; | 
|---|
| 974 |     // 引数チェック | 
|---|
| 975 |     if (sec == NULL) | 
|---|
| 976 |     { | 
|---|
| 977 |         return false; | 
|---|
| 978 |     } | 
|---|
| 979 |     if (name == NULL) | 
|---|
| 980 |     { | 
|---|
| 981 |         sec->Error = SEC_ERROR_BAD_PARAMETER; | 
|---|
| 982 |         return false; | 
|---|
| 983 |     } | 
|---|
| 984 |     if (sec->SessionCreated == false) | 
|---|
| 985 |     { | 
|---|
| 986 |         sec->Error = SEC_ERROR_NO_SESSION; | 
|---|
| 987 |         return 0; | 
|---|
| 988 |     } | 
|---|
| 989 |  | 
|---|
| 990 |     obj = FindSecObject(sec, name, type); | 
|---|
| 991 |  | 
|---|
| 992 |     if (obj == NULL) | 
|---|
| 993 |     { | 
|---|
| 994 |         return false; | 
|---|
| 995 |     } | 
|---|
| 996 |     else | 
|---|
| 997 |     { | 
|---|
| 998 |         FreeSecObject(obj); | 
|---|
| 999 |         return true; | 
|---|
| 1000 |     } | 
|---|
| 1001 | } | 
|---|
| 1002 |  | 
|---|
| 1003 | // セキュアオブジェクト構造体のクローンの作成 | 
|---|
| 1004 | SEC_OBJ *CloneSecObject(SEC_OBJ *obj) | 
|---|
| 1005 | { | 
|---|
| 1006 |     SEC_OBJ *ret; | 
|---|
| 1007 |     // 引数チェック | 
|---|
| 1008 |     if (obj == NULL) | 
|---|
| 1009 |     { | 
|---|
| 1010 |         return NULL; | 
|---|
| 1011 |     } | 
|---|
| 1012 |  | 
|---|
| 1013 |     ret = ZeroMalloc(sizeof(SEC_OBJ)); | 
|---|
| 1014 |     ret->Name = CopyStr(obj->Name); | 
|---|
| 1015 |     ret->Object = obj->Object; | 
|---|
| 1016 |     ret->Private = obj->Private; | 
|---|
| 1017 |     ret->Type = obj->Type; | 
|---|
| 1018 |  | 
|---|
| 1019 |     return ret; | 
|---|
| 1020 | } | 
|---|
| 1021 |  | 
|---|
| 1022 | // セキュアオブジェクトを名前で検索して取得する | 
|---|
| 1023 | SEC_OBJ *FindSecObject(SECURE *sec, char *name, UINT type) | 
|---|
| 1024 | { | 
|---|
| 1025 |     LIST *o; | 
|---|
| 1026 |     UINT i; | 
|---|
| 1027 |     SEC_OBJ *ret = NULL; | 
|---|
| 1028 |     // 引数チェック | 
|---|
| 1029 |     if (sec == NULL) | 
|---|
| 1030 |     { | 
|---|
| 1031 |         return NULL; | 
|---|
| 1032 |     } | 
|---|
| 1033 |     if (name == NULL) | 
|---|
| 1034 |     { | 
|---|
| 1035 |         sec->Error = SEC_ERROR_BAD_PARAMETER; | 
|---|
| 1036 |         return NULL; | 
|---|
| 1037 |     } | 
|---|
| 1038 |     if (sec->SessionCreated == false) | 
|---|
| 1039 |     { | 
|---|
| 1040 |         sec->Error = SEC_ERROR_NO_SESSION; | 
|---|
| 1041 |         return 0; | 
|---|
| 1042 |     } | 
|---|
| 1043 |  | 
|---|
| 1044 |     // 列挙 | 
|---|
| 1045 |     o = EnumSecObject(sec); | 
|---|
| 1046 |     if (o == NULL) | 
|---|
| 1047 |     { | 
|---|
| 1048 |         return NULL; | 
|---|
| 1049 |     } | 
|---|
| 1050 |     for (i = 0;i < LIST_NUM(o);i++) | 
|---|
| 1051 |     { | 
|---|
| 1052 |         SEC_OBJ *obj = LIST_DATA(o, i); | 
|---|
| 1053 |  | 
|---|
| 1054 |         if (obj->Type == type || type == INFINITE) | 
|---|
| 1055 |         { | 
|---|
| 1056 |             if (StrCmpi(obj->Name, name) == 0) | 
|---|
| 1057 |             { | 
|---|
| 1058 |                 ret = CloneSecObject(obj); | 
|---|
| 1059 |                 break; | 
|---|
| 1060 |             } | 
|---|
| 1061 |         } | 
|---|
| 1062 |     } | 
|---|
| 1063 |     FreeEnumSecObject(o); | 
|---|
| 1064 |  | 
|---|
| 1065 |     if (ret == NULL) | 
|---|
| 1066 |     { | 
|---|
| 1067 |         sec->Error = SEC_ERROR_OBJ_NOT_FOUND; | 
|---|
| 1068 |     } | 
|---|
| 1069 |  | 
|---|
| 1070 |     return ret; | 
|---|
| 1071 | } | 
|---|
| 1072 |  | 
|---|
| 1073 | // セキュアオブジェクトの読み込み | 
|---|
| 1074 | int ReadSecDataFromObject(SECURE *sec, SEC_OBJ *obj, void *data, UINT size) | 
|---|
| 1075 | { | 
|---|
| 1076 |     UCHAR buf[MAX_SEC_DATA_SIZE]; | 
|---|
| 1077 |     UINT i; | 
|---|
| 1078 |     CK_ATTRIBUTE get[] = | 
|---|
| 1079 |     { | 
|---|
| 1080 |         {CKA_VALUE,  buf,   sizeof(buf)}, | 
|---|
| 1081 |     }; | 
|---|
| 1082 |     // 引数チェック | 
|---|
| 1083 |     if (sec == NULL) | 
|---|
| 1084 |     { | 
|---|
| 1085 |         return 0; | 
|---|
| 1086 |     } | 
|---|
| 1087 |     if (obj == NULL || data == NULL || size == 0) | 
|---|
| 1088 |     { | 
|---|
| 1089 |         sec->Error = SEC_ERROR_BAD_PARAMETER; | 
|---|
| 1090 |         return 0; | 
|---|
| 1091 |     } | 
|---|
| 1092 |     if (obj->Type != SEC_DATA) | 
|---|
| 1093 |     { | 
|---|
| 1094 |         sec->Error = SEC_ERROR_BAD_PARAMETER; | 
|---|
| 1095 |         return false; | 
|---|
| 1096 |     } | 
|---|
| 1097 |     if (sec->SessionCreated == false) | 
|---|
| 1098 |     { | 
|---|
| 1099 |         sec->Error = SEC_ERROR_NO_SESSION; | 
|---|
| 1100 |         return 0; | 
|---|
| 1101 |     } | 
|---|
| 1102 |     if (sec->LoginFlag == false && obj->Private) | 
|---|
| 1103 |     { | 
|---|
| 1104 |         sec->Error = SEC_ERROR_NOT_LOGIN; | 
|---|
| 1105 |         return 0; | 
|---|
| 1106 |     } | 
|---|
| 1107 |  | 
|---|
| 1108 |     // 取得 | 
|---|
| 1109 |     if (sec->Api->C_GetAttributeValue( | 
|---|
| 1110 |         sec->SessionId, obj->Object, get, sizeof(get) / sizeof(get[0])) != CKR_OK) | 
|---|
| 1111 |     { | 
|---|
| 1112 |         sec->Error = SEC_ERROR_HARDWARE_ERROR; | 
|---|
| 1113 |         return 0; | 
|---|
| 1114 |     } | 
|---|
| 1115 |  | 
|---|
| 1116 |     // 結果の返却 | 
|---|
| 1117 |     i = get[0].ulValueLen; | 
|---|
| 1118 |     if (i > MAX_SEC_DATA_SIZE || i > size) | 
|---|
| 1119 |     { | 
|---|
| 1120 |         // データが大きすぎる | 
|---|
| 1121 |         sec->Error = SEC_ERROR_DATA_TOO_BIG; | 
|---|
| 1122 |         return 0; | 
|---|
| 1123 |     } | 
|---|
| 1124 |  | 
|---|
| 1125 |     // メモリコピー | 
|---|
| 1126 |     Copy(data, buf, i); | 
|---|
| 1127 |  | 
|---|
| 1128 |     return i; | 
|---|
| 1129 | } | 
|---|
| 1130 |  | 
|---|
| 1131 | // セキュアオブジェクトの列挙結果の解放 | 
|---|
| 1132 | void FreeEnumSecObject(LIST *o) | 
|---|
| 1133 | { | 
|---|
| 1134 |     UINT i; | 
|---|
| 1135 |     // 引数チェック | 
|---|
| 1136 |     if (o == NULL) | 
|---|
| 1137 |     { | 
|---|
| 1138 |         return; | 
|---|
| 1139 |     } | 
|---|
| 1140 |  | 
|---|
| 1141 |     for (i = 0;i < LIST_NUM(o);i++) | 
|---|
| 1142 |     { | 
|---|
| 1143 |         SEC_OBJ *obj = LIST_DATA(o, i); | 
|---|
| 1144 |  | 
|---|
| 1145 |         FreeSecObject(obj); | 
|---|
| 1146 |     } | 
|---|
| 1147 |  | 
|---|
| 1148 |     ReleaseList(o); | 
|---|
| 1149 | } | 
|---|
| 1150 |  | 
|---|
| 1151 | // セキュアオブジェクトの解放 | 
|---|
| 1152 | void FreeSecObject(SEC_OBJ *obj) | 
|---|
| 1153 | { | 
|---|
| 1154 |     // 引数チェック | 
|---|
| 1155 |     if (obj == NULL) | 
|---|
| 1156 |     { | 
|---|
| 1157 |         return; | 
|---|
| 1158 |     } | 
|---|
| 1159 |  | 
|---|
| 1160 |     Free(obj->Name); | 
|---|
| 1161 |     Free(obj); | 
|---|
| 1162 | } | 
|---|
| 1163 |  | 
|---|
| 1164 | // セキュアオブジェクト列挙結果のクローン | 
|---|
| 1165 | LIST *CloneEnumSecObject(LIST *o) | 
|---|
| 1166 | { | 
|---|
| 1167 |     LIST *ret; | 
|---|
| 1168 |     UINT i; | 
|---|
| 1169 |     // 引数チェック | 
|---|
| 1170 |     if (o == NULL) | 
|---|
| 1171 |     { | 
|---|
| 1172 |         return NULL; | 
|---|
| 1173 |     } | 
|---|
| 1174 |  | 
|---|
| 1175 |     ret = NewListFast(NULL); | 
|---|
| 1176 |     for (i = 0;i < LIST_NUM(o);i++) | 
|---|
| 1177 |     { | 
|---|
| 1178 |         SEC_OBJ *obj = LIST_DATA(o, i); | 
|---|
| 1179 |  | 
|---|
| 1180 |         Add(ret, CloneSecObject(obj)); | 
|---|
| 1181 |     } | 
|---|
| 1182 |  | 
|---|
| 1183 |     return ret; | 
|---|
| 1184 | } | 
|---|
| 1185 |  | 
|---|
| 1186 | // セキュアオブジェクトの列挙 | 
|---|
| 1187 | LIST *EnumSecObject(SECURE *sec) | 
|---|
| 1188 | { | 
|---|
| 1189 |     CK_BBOOL b_true = true, b_false = false; | 
|---|
| 1190 |     UINT objects[MAX_OBJ]; | 
|---|
| 1191 |     UINT i; | 
|---|
| 1192 |     UINT ret; | 
|---|
| 1193 |     LIST *o; | 
|---|
| 1194 |     CK_ATTRIBUTE dummy[1]; | 
|---|
| 1195 |     CK_ATTRIBUTE a[] = | 
|---|
| 1196 |     { | 
|---|
| 1197 |         {CKA_TOKEN,     &b_true,        sizeof(b_true)}, | 
|---|
| 1198 |     }; | 
|---|
| 1199 |     UINT num_objects = MAX_OBJ; | 
|---|
| 1200 |     // 引数チェック | 
|---|
| 1201 |     if (sec == NULL) | 
|---|
| 1202 |     { | 
|---|
| 1203 |         return NULL; | 
|---|
| 1204 |     } | 
|---|
| 1205 |     if (sec->SessionCreated == false) | 
|---|
| 1206 |     { | 
|---|
| 1207 |         sec->Error = SEC_ERROR_NO_SESSION; | 
|---|
| 1208 |         return NULL; | 
|---|
| 1209 |     } | 
|---|
| 1210 |  | 
|---|
| 1211 |     Zero(dummy, sizeof(dummy)); | 
|---|
| 1212 |  | 
|---|
| 1213 |     // キャッシュがあればキャッシュを返す | 
|---|
| 1214 |     if (sec->EnumCache != NULL) | 
|---|
| 1215 |     { | 
|---|
| 1216 |         return CloneEnumSecObject(sec->EnumCache); | 
|---|
| 1217 |     } | 
|---|
| 1218 |  | 
|---|
| 1219 |     // 列挙 | 
|---|
| 1220 | //  if (sec->Dev->Id != 2 && sec->Dev->Id != 14) | 
|---|
| 1221 | //  { | 
|---|
| 1222 |         // 通常のトークン | 
|---|
| 1223 |         ret = sec->Api->C_FindObjectsInit(sec->SessionId, a, sizeof(a) / sizeof(a[0])); | 
|---|
| 1224 | //  } | 
|---|
| 1225 | //  else | 
|---|
| 1226 | //  { | 
|---|
| 1227 |         // ePass と SafeSign | 
|---|
| 1228 | //      ret = sec->Api->C_FindObjectsInit(sec->SessionId, dummy, 0); | 
|---|
| 1229 | //  } | 
|---|
| 1230 |  | 
|---|
| 1231 |     if (ret != CKR_OK) | 
|---|
| 1232 |     { | 
|---|
| 1233 |         sec->Error = SEC_ERROR_HARDWARE_ERROR; | 
|---|
| 1234 |         return NULL; | 
|---|
| 1235 |     } | 
|---|
| 1236 |     if (sec->Api->C_FindObjects(sec->SessionId, objects, sizeof(objects) / sizeof(objects[0]), &num_objects) != CKR_OK) | 
|---|
| 1237 |     { | 
|---|
| 1238 |         sec->Api->C_FindObjectsFinal(sec->SessionId); | 
|---|
| 1239 |         sec->Error = SEC_ERROR_HARDWARE_ERROR; | 
|---|
| 1240 |         return NULL; | 
|---|
| 1241 |     } | 
|---|
| 1242 |     sec->Api->C_FindObjectsFinal(sec->SessionId); | 
|---|
| 1243 |  | 
|---|
| 1244 |     o = NewListFast(NULL); | 
|---|
| 1245 |  | 
|---|
| 1246 |     for (i = 0;i < num_objects;i++) | 
|---|
| 1247 |     { | 
|---|
| 1248 |         char label[MAX_SIZE]; | 
|---|
| 1249 |         UINT obj_class = 0; | 
|---|
| 1250 |         bool priv = false; | 
|---|
| 1251 |         CK_ATTRIBUTE get[] = | 
|---|
| 1252 |         { | 
|---|
| 1253 |             {CKA_LABEL, label, sizeof(label) - 1}, | 
|---|
| 1254 |             {CKA_CLASS, &obj_class, sizeof(obj_class)}, | 
|---|
| 1255 |             {CKA_PRIVATE, &priv, sizeof(priv)}, | 
|---|
| 1256 |         }; | 
|---|
| 1257 |  | 
|---|
| 1258 |         Zero(label, sizeof(label)); | 
|---|
| 1259 |  | 
|---|
| 1260 |         if (sec->Api->C_GetAttributeValue(sec->SessionId, objects[i], | 
|---|
| 1261 |             get, sizeof(get) / sizeof(get[0])) == CKR_OK) | 
|---|
| 1262 |         { | 
|---|
| 1263 |             UINT type = INFINITE; | 
|---|
| 1264 |  | 
|---|
| 1265 |             switch (obj_class) | 
|---|
| 1266 |             { | 
|---|
| 1267 |             case CKO_DATA: | 
|---|
| 1268 |                 // データ | 
|---|
| 1269 |                 type = SEC_DATA; | 
|---|
| 1270 |                 break; | 
|---|
| 1271 |  | 
|---|
| 1272 |             case CKO_CERTIFICATE: | 
|---|
| 1273 |                 // 証明書 | 
|---|
| 1274 |                 type = SEC_X; | 
|---|
| 1275 |                 break; | 
|---|
| 1276 |  | 
|---|
| 1277 |             case CKO_PUBLIC_KEY: | 
|---|
| 1278 |                 // 公開鍵 | 
|---|
| 1279 |                 type = SEC_P; | 
|---|
| 1280 |                 break; | 
|---|
| 1281 |  | 
|---|
| 1282 |             case CKO_PRIVATE_KEY: | 
|---|
| 1283 |                 // 秘密鍵 | 
|---|
| 1284 |                 type = SEC_K; | 
|---|
| 1285 |                 break; | 
|---|
| 1286 |             } | 
|---|
| 1287 |  | 
|---|
| 1288 |             if (type != INFINITE) | 
|---|
| 1289 |             { | 
|---|
| 1290 |                 SEC_OBJ *obj = ZeroMalloc(sizeof(SEC_OBJ)); | 
|---|
| 1291 |  | 
|---|
| 1292 |                 obj->Type = type; | 
|---|
| 1293 |                 obj->Object = objects[i]; | 
|---|
| 1294 |                 obj->Private = (priv == false) ? false : true; | 
|---|
| 1295 |                 EnSafeStr(label, '?'); | 
|---|
| 1296 |                 TruncateCharFromStr(label, '?'); | 
|---|
| 1297 |                 obj->Name = CopyStr(label); | 
|---|
| 1298 |  | 
|---|
| 1299 |                 Add(o, obj); | 
|---|
| 1300 |             } | 
|---|
| 1301 |         } | 
|---|
| 1302 |     } | 
|---|
| 1303 |  | 
|---|
| 1304 |     // キャッシュ作成 | 
|---|
| 1305 |     sec->EnumCache = CloneEnumSecObject(o); | 
|---|
| 1306 |  | 
|---|
| 1307 |     return o; | 
|---|
| 1308 | } | 
|---|
| 1309 |  | 
|---|
| 1310 | // データを書き込む | 
|---|
| 1311 | bool WriteSecData(SECURE *sec, bool private_obj, char *name, void *data, UINT size) | 
|---|
| 1312 | { | 
|---|
| 1313 |     UINT object_class = CKO_DATA; | 
|---|
| 1314 |     CK_BBOOL b_true = true, b_false = false, b_private_obj = private_obj; | 
|---|
| 1315 |     UINT object; | 
|---|
| 1316 |     CK_ATTRIBUTE a[] = | 
|---|
| 1317 |     { | 
|---|
| 1318 |         {CKA_TOKEN,     &b_true,        sizeof(b_true)}, | 
|---|
| 1319 |         {CKA_CLASS,     &object_class,  sizeof(object_class)}, | 
|---|
| 1320 |         {CKA_PRIVATE,   &b_private_obj, sizeof(b_private_obj)}, | 
|---|
| 1321 |         {CKA_LABEL,     name,           StrLen(name)}, | 
|---|
| 1322 |         {CKA_VALUE,     data,           size}, | 
|---|
| 1323 |     }; | 
|---|
| 1324 |     // 引数チェック | 
|---|
| 1325 |     if (sec == NULL) | 
|---|
| 1326 |     { | 
|---|
| 1327 |         return false; | 
|---|
| 1328 |     } | 
|---|
| 1329 |     if (sec->SessionCreated == false) | 
|---|
| 1330 |     { | 
|---|
| 1331 |         sec->Error = SEC_ERROR_NO_SESSION; | 
|---|
| 1332 |         return false; | 
|---|
| 1333 |     } | 
|---|
| 1334 |     if (private_obj && sec->LoginFlag == false) | 
|---|
| 1335 |     { | 
|---|
| 1336 |         sec->Error = SEC_ERROR_NOT_LOGIN; | 
|---|
| 1337 |         return false; | 
|---|
| 1338 |     } | 
|---|
| 1339 |     if (name == NULL || data == NULL || size == 0) | 
|---|
| 1340 |     { | 
|---|
| 1341 |         sec->Error = SEC_ERROR_BAD_PARAMETER; | 
|---|
| 1342 |         return false; | 
|---|
| 1343 |     } | 
|---|
| 1344 |     if (size > MAX_SEC_DATA_SIZE) | 
|---|
| 1345 |     { | 
|---|
| 1346 |         sec->Error = SEC_ERROR_DATA_TOO_BIG; | 
|---|
| 1347 |         return false; | 
|---|
| 1348 |     } | 
|---|
| 1349 |  | 
|---|
| 1350 |     // 同名のオブジェクトがあれば削除 | 
|---|
| 1351 |     if (CheckSecObject(sec, name, SEC_DATA)) | 
|---|
| 1352 |     { | 
|---|
| 1353 |         DeleteSecData(sec, name); | 
|---|
| 1354 |     } | 
|---|
| 1355 |  | 
|---|
| 1356 |     // オブジェクト作成 | 
|---|
| 1357 |     if (sec->Api->C_CreateObject(sec->SessionId, a, sizeof(a) / sizeof(a[0]), &object) != CKR_OK) | 
|---|
| 1358 |     { | 
|---|
| 1359 |         sec->Error = SEC_ERROR_HARDWARE_ERROR; | 
|---|
| 1360 |         return false; | 
|---|
| 1361 |     } | 
|---|
| 1362 |  | 
|---|
| 1363 |     // キャッシュ消去 | 
|---|
| 1364 |     EraseEnumSecObjectCache(sec); | 
|---|
| 1365 |  | 
|---|
| 1366 |     return true; | 
|---|
| 1367 | } | 
|---|
| 1368 |  | 
|---|
| 1369 | // キャッシュに新規作成したオブジェクトの情報を追加する | 
|---|
| 1370 | void AddSecObjToEnumCache(SECURE *sec, char *name, UINT type, bool private_obj, UINT object) | 
|---|
| 1371 | { | 
|---|
| 1372 |     SEC_OBJ *obj; | 
|---|
| 1373 |     // 引数チェック | 
|---|
| 1374 |     if (sec == NULL || name == NULL || sec->EnumCache == NULL) | 
|---|
| 1375 |     { | 
|---|
| 1376 |         return; | 
|---|
| 1377 |     } | 
|---|
| 1378 |  | 
|---|
| 1379 |     obj = ZeroMalloc(sizeof(SEC_OBJ)); | 
|---|
| 1380 |     obj->Name = CopyStr(name); | 
|---|
| 1381 |     obj->Object = object; | 
|---|
| 1382 |     obj->Private = private_obj; | 
|---|
| 1383 |     obj->Type = type; | 
|---|
| 1384 |  | 
|---|
| 1385 |     Add(sec->EnumCache, obj); | 
|---|
| 1386 | } | 
|---|
| 1387 |  | 
|---|
| 1388 | // トークン情報を表示 | 
|---|
| 1389 | void PrintSecInfo(SECURE *sec) | 
|---|
| 1390 | { | 
|---|
| 1391 |     SEC_INFO *s; | 
|---|
| 1392 |     // 引数チェック | 
|---|
| 1393 |     if (sec == NULL) | 
|---|
| 1394 |     { | 
|---|
| 1395 |         return; | 
|---|
| 1396 |     } | 
|---|
| 1397 |  | 
|---|
| 1398 |     s = sec->Info; | 
|---|
| 1399 |     if (s == NULL) | 
|---|
| 1400 |     { | 
|---|
| 1401 |         Print("No Token Info.\n"); | 
|---|
| 1402 |         return; | 
|---|
| 1403 |     } | 
|---|
| 1404 |  | 
|---|
| 1405 |     Print( | 
|---|
| 1406 |         "               Label: %S\n" | 
|---|
| 1407 |         "      ManufacturerId: %S\n" | 
|---|
| 1408 |         "               Model: %S\n" | 
|---|
| 1409 |         "        SerialNumber: %S\n" | 
|---|
| 1410 |         "          MaxSession: %u\n" | 
|---|
| 1411 |         "        MaxRWSession: %u\n" | 
|---|
| 1412 |         "           MinPinLen: %u\n" | 
|---|
| 1413 |         "           MaxPinLen: %u\n" | 
|---|
| 1414 |         "   TotalPublicMemory: %u\n" | 
|---|
| 1415 |         "    FreePublicMemory: %u\n" | 
|---|
| 1416 |         "  TotalPrivateMemory: %u\n" | 
|---|
| 1417 |         "   FreePrivateMemory: %u\n" | 
|---|
| 1418 |         "     HardwareVersion: %s\n" | 
|---|
| 1419 |         "     FirmwareVersion: %s\n", | 
|---|
| 1420 |         s->Label, s->ManufacturerId, s->Model, s->SerialNumber, | 
|---|
| 1421 |         s->MaxSession, s->MaxRWSession, s->MinPinLen, s->MaxPinLen, | 
|---|
| 1422 |         s->TotalPublicMemory, s->FreePublicMemory, s->TotalPrivateMemory, | 
|---|
| 1423 |         s->FreePrivateMemory, s->HardwareVersion, s->FirmwareVersion | 
|---|
| 1424 |         ); | 
|---|
| 1425 | } | 
|---|
| 1426 |  | 
|---|
| 1427 | // トークン情報を取得 | 
|---|
| 1428 | void GetSecInfo(SECURE *sec) | 
|---|
| 1429 | { | 
|---|
| 1430 |     CK_TOKEN_INFO token_info; | 
|---|
| 1431 |     // 引数チェック | 
|---|
| 1432 |     if (sec == NULL) | 
|---|
| 1433 |     { | 
|---|
| 1434 |         return; | 
|---|
| 1435 |     } | 
|---|
| 1436 |     if (sec->Info != NULL) | 
|---|
| 1437 |     { | 
|---|
| 1438 |         return; | 
|---|
| 1439 |     } | 
|---|
| 1440 |  | 
|---|
| 1441 |     // 取得 | 
|---|
| 1442 |     Zero(&token_info, sizeof(token_info)); | 
|---|
| 1443 |     if (sec->Api->C_GetTokenInfo(sec->SlotIdList[sec->SessionSlotNumber], &token_info) != CKR_OK) | 
|---|
| 1444 |     { | 
|---|
| 1445 |         // 失敗 | 
|---|
| 1446 |         return; | 
|---|
| 1447 |     } | 
|---|
| 1448 |  | 
|---|
| 1449 |     sec->Info = TokenInfoToSecInfo(&token_info); | 
|---|
| 1450 | } | 
|---|
| 1451 |  | 
|---|
| 1452 | // トークン情報を解放 | 
|---|
| 1453 | void FreeSecInfo(SECURE *sec) | 
|---|
| 1454 | { | 
|---|
| 1455 |     // 引数チェック | 
|---|
| 1456 |     if (sec == NULL) | 
|---|
| 1457 |     { | 
|---|
| 1458 |         return; | 
|---|
| 1459 |     } | 
|---|
| 1460 |     if (sec->Info == NULL) | 
|---|
| 1461 |     { | 
|---|
| 1462 |         return; | 
|---|
| 1463 |     } | 
|---|
| 1464 |  | 
|---|
| 1465 |     FreeSecInfoMemory(sec->Info); | 
|---|
| 1466 |     sec->Info = NULL; | 
|---|
| 1467 | } | 
|---|
| 1468 |  | 
|---|
| 1469 | // トークン情報を SEC_INFO に変換 | 
|---|
| 1470 | SEC_INFO *TokenInfoToSecInfo(void *p_t) | 
|---|
| 1471 | { | 
|---|
| 1472 |     SEC_INFO *s; | 
|---|
| 1473 |     char buf[MAX_SIZE]; | 
|---|
| 1474 |     CK_TOKEN_INFO *t = (CK_TOKEN_INFO *)p_t; | 
|---|
| 1475 |     // 引数チェック | 
|---|
| 1476 |     if (t == NULL) | 
|---|
| 1477 |     { | 
|---|
| 1478 |         return NULL; | 
|---|
| 1479 |     } | 
|---|
| 1480 |  | 
|---|
| 1481 |     s = ZeroMalloc(sizeof(SEC_INFO)); | 
|---|
| 1482 |  | 
|---|
| 1483 |     // Label | 
|---|
| 1484 |     Zero(buf, sizeof(buf)); | 
|---|
| 1485 |     Copy(buf, t->label, sizeof(t->label)); | 
|---|
| 1486 |     s->Label = ZeroMalloc(CalcUtf8ToUni(buf, 0)); | 
|---|
| 1487 |     Utf8ToUni(s->Label, 0, buf, 0); | 
|---|
| 1488 |  | 
|---|
| 1489 |     // ManufacturerId | 
|---|
| 1490 |     Zero(buf, sizeof(buf)); | 
|---|
| 1491 |     Copy(buf, t->manufacturerID, sizeof(t->manufacturerID)); | 
|---|
| 1492 |     s->ManufacturerId = ZeroMalloc(CalcUtf8ToUni(buf, 0)); | 
|---|
| 1493 |     Utf8ToUni(s->ManufacturerId, 0, buf, 0); | 
|---|
| 1494 |  | 
|---|
| 1495 |     // Model | 
|---|
| 1496 |     Zero(buf, sizeof(buf)); | 
|---|
| 1497 |     Copy(buf, t->model, sizeof(t->model)); | 
|---|
| 1498 |     s->Model = ZeroMalloc(CalcUtf8ToUni(buf, 0)); | 
|---|
| 1499 |     Utf8ToUni(s->Model, 0, buf, 0); | 
|---|
| 1500 |  | 
|---|
| 1501 |     // SerialNumber | 
|---|
| 1502 |     Zero(buf, sizeof(buf)); | 
|---|
| 1503 |     Copy(buf, t->serialNumber, sizeof(t->serialNumber)); | 
|---|
| 1504 |     s->SerialNumber = ZeroMalloc(CalcUtf8ToUni(buf, 0)); | 
|---|
| 1505 |     Utf8ToUni(s->SerialNumber, 0, buf, 0); | 
|---|
| 1506 |  | 
|---|
| 1507 |     // 数値 | 
|---|
| 1508 |     s->MaxSession = t->ulMaxSessionCount; | 
|---|
| 1509 |     s->MaxRWSession = t->ulMaxRwSessionCount; | 
|---|
| 1510 |     s->MinPinLen = t->ulMinPinLen; | 
|---|
| 1511 |     s->MaxPinLen = t->ulMaxPinLen; | 
|---|
| 1512 |     s->TotalPublicMemory = t->ulTotalPublicMemory; | 
|---|
| 1513 |     s->FreePublicMemory = t->ulFreePublicMemory; | 
|---|
| 1514 |     s->TotalPrivateMemory = t->ulTotalPrivateMemory; | 
|---|
| 1515 |     s->FreePrivateMemory = t->ulFreePrivateMemory; | 
|---|
| 1516 |  | 
|---|
| 1517 |     // ハードウェアバージョン | 
|---|
| 1518 |     Format(buf, sizeof(buf), "%u.%02u", t->hardwareVersion.major, t->hardwareVersion.minor); | 
|---|
| 1519 |     s->HardwareVersion = CopyStr(buf); | 
|---|
| 1520 |  | 
|---|
| 1521 |     // ファームウェアバージョン | 
|---|
| 1522 |     Format(buf, sizeof(buf), "%u.%02u", t->firmwareVersion.major, t->firmwareVersion.minor); | 
|---|
| 1523 |     s->FirmwareVersion = CopyStr(buf); | 
|---|
| 1524 |  | 
|---|
| 1525 |     return s; | 
|---|
| 1526 | } | 
|---|
| 1527 |  | 
|---|
| 1528 | // SEC_INFO のメモリを解放 | 
|---|
| 1529 | void FreeSecInfoMemory(SEC_INFO *s) | 
|---|
| 1530 | { | 
|---|
| 1531 |     // 引数チェック | 
|---|
| 1532 |     if (s == NULL) | 
|---|
| 1533 |     { | 
|---|
| 1534 |         return; | 
|---|
| 1535 |     } | 
|---|
| 1536 |  | 
|---|
| 1537 |     Free(s->Label); | 
|---|
| 1538 |     Free(s->ManufacturerId); | 
|---|
| 1539 |     Free(s->Model); | 
|---|
| 1540 |     Free(s->SerialNumber); | 
|---|
| 1541 |     Free(s->HardwareVersion); | 
|---|
| 1542 |     Free(s->FirmwareVersion); | 
|---|
| 1543 |     Free(s); | 
|---|
| 1544 | } | 
|---|
| 1545 |  | 
|---|
| 1546 | // ログアウトする | 
|---|
| 1547 | void LogoutSec(SECURE *sec) | 
|---|
| 1548 | { | 
|---|
| 1549 |     // 引数チェック | 
|---|
| 1550 |     if (sec == NULL) | 
|---|
| 1551 |     { | 
|---|
| 1552 |         return; | 
|---|
| 1553 |     } | 
|---|
| 1554 |     if (sec->LoginFlag == false) | 
|---|
| 1555 |     { | 
|---|
| 1556 |         return; | 
|---|
| 1557 |     } | 
|---|
| 1558 |  | 
|---|
| 1559 |     // ログアウト | 
|---|
| 1560 |     sec->Api->C_Logout(sec->SessionId); | 
|---|
| 1561 |  | 
|---|
| 1562 |     // キャッシュ消去 | 
|---|
| 1563 |     EraseEnumSecObjectCache(sec); | 
|---|
| 1564 |  | 
|---|
| 1565 |     sec->LoginFlag = false; | 
|---|
| 1566 | } | 
|---|
| 1567 |  | 
|---|
| 1568 | // ログインする | 
|---|
| 1569 | bool LoginSec(SECURE *sec, char *pin) | 
|---|
| 1570 | { | 
|---|
| 1571 |     // 引数チェック | 
|---|
| 1572 |     if (sec == NULL) | 
|---|
| 1573 |     { | 
|---|
| 1574 |         return false; | 
|---|
| 1575 |     } | 
|---|
| 1576 |     if (sec->SessionCreated == false) | 
|---|
| 1577 |     { | 
|---|
| 1578 |         sec->Error = SEC_ERROR_NO_SESSION; | 
|---|
| 1579 |         return false; | 
|---|
| 1580 |  | 
|---|
| 1581 |     } | 
|---|
| 1582 |     if (sec->LoginFlag) | 
|---|
| 1583 |     { | 
|---|
| 1584 |         sec->Error = SEC_ERROR_ALREADY_LOGIN; | 
|---|
| 1585 |         return false; | 
|---|
| 1586 |     } | 
|---|
| 1587 |     if (pin == NULL) | 
|---|
| 1588 |     { | 
|---|
| 1589 |         sec->Error = SEC_ERROR_NO_PIN_STR; | 
|---|
| 1590 |         return false; | 
|---|
| 1591 |     } | 
|---|
| 1592 |  | 
|---|
| 1593 |     // ログイン | 
|---|
| 1594 |     if (sec->Api->C_Login(sec->SessionId, CKU_USER, pin, StrLen(pin)) != CKR_OK) | 
|---|
| 1595 |     { | 
|---|
| 1596 |         // ログイン失敗 | 
|---|
| 1597 |         sec->Error = SEC_ERROR_BAD_PIN_CODE; | 
|---|
| 1598 |         return false; | 
|---|
| 1599 |     } | 
|---|
| 1600 |  | 
|---|
| 1601 |     // キャッシュ消去 | 
|---|
| 1602 |     EraseEnumSecObjectCache(sec); | 
|---|
| 1603 |  | 
|---|
| 1604 |     sec->LoginFlag = true; | 
|---|
| 1605 |  | 
|---|
| 1606 |     return true; | 
|---|
| 1607 | } | 
|---|
| 1608 |  | 
|---|
| 1609 | // セッションを閉じる | 
|---|
| 1610 | void CloseSecSession(SECURE *sec) | 
|---|
| 1611 | { | 
|---|
| 1612 |     // 引数チェック | 
|---|
| 1613 |     if (sec == NULL) | 
|---|
| 1614 |     { | 
|---|
| 1615 |         return; | 
|---|
| 1616 |     } | 
|---|
| 1617 |     if (sec->SessionCreated == false) | 
|---|
| 1618 |     { | 
|---|
| 1619 |         return; | 
|---|
| 1620 |     } | 
|---|
| 1621 |  | 
|---|
| 1622 |     // セッションを閉じる | 
|---|
| 1623 |     sec->Api->C_CloseSession(sec->SessionId); | 
|---|
| 1624 |  | 
|---|
| 1625 |     sec->SessionCreated = false; | 
|---|
| 1626 |     sec->SessionId = 0; | 
|---|
| 1627 |     sec->SessionSlotNumber = 0; | 
|---|
| 1628 |  | 
|---|
| 1629 |     FreeSecInfo(sec); | 
|---|
| 1630 |  | 
|---|
| 1631 |     // キャッシュ消去 | 
|---|
| 1632 |     EraseEnumSecObjectCache(sec); | 
|---|
| 1633 | } | 
|---|
| 1634 |  | 
|---|
| 1635 | // セッションを開く | 
|---|
| 1636 | bool OpenSecSession(SECURE *sec, UINT slot_number) | 
|---|
| 1637 | { | 
|---|
| 1638 |     UINT err = 0; | 
|---|
| 1639 |     UINT session; | 
|---|
| 1640 |     // 引数チェック | 
|---|
| 1641 |     if (sec == NULL) | 
|---|
| 1642 |     { | 
|---|
| 1643 |         return false; | 
|---|
| 1644 |     } | 
|---|
| 1645 |     if (sec->SessionCreated) | 
|---|
| 1646 |     { | 
|---|
| 1647 |         // すでに作成されている | 
|---|
| 1648 |         sec->Error = SEC_ERROR_SESSION_EXISTS; | 
|---|
| 1649 |         return false; | 
|---|
| 1650 |     } | 
|---|
| 1651 |     if (slot_number >= sec->NumSlot) | 
|---|
| 1652 |     { | 
|---|
| 1653 |         // スロット番号不正 | 
|---|
| 1654 |         sec->Error = SEC_ERROR_INVALID_SLOT_NUMBER; | 
|---|
| 1655 |         return false; | 
|---|
| 1656 |     } | 
|---|
| 1657 |  | 
|---|
| 1658 |     // セッション作成 | 
|---|
| 1659 |     if ((err = sec->Api->C_OpenSession(sec->SlotIdList[slot_number], | 
|---|
| 1660 |         CKF_RW_SESSION | CKF_SERIAL_SESSION, NULL, NULL, &session)) != CKR_OK) | 
|---|
| 1661 |     { | 
|---|
| 1662 |         // 読み書きモードでのセッション初期化に失敗した | 
|---|
| 1663 |         // 読み取り専用モードかな? | 
|---|
| 1664 |         if ((err = sec->Api->C_OpenSession(sec->SlotIdList[slot_number], | 
|---|
| 1665 |             CKF_SERIAL_SESSION, NULL, NULL, &session)) != CKR_OK) | 
|---|
| 1666 |         { | 
|---|
| 1667 |             // 作成失敗 | 
|---|
| 1668 |             sec->Error = SEC_ERROR_OPEN_SESSION; | 
|---|
| 1669 |             return false; | 
|---|
| 1670 |         } | 
|---|
| 1671 |         else | 
|---|
| 1672 |         { | 
|---|
| 1673 |             sec->IsReadOnly = true; | 
|---|
| 1674 |         } | 
|---|
| 1675 |     } | 
|---|
| 1676 |  | 
|---|
| 1677 |     sec->SessionCreated = true; | 
|---|
| 1678 |     sec->SessionId = session; | 
|---|
| 1679 |     sec->SessionSlotNumber = slot_number; | 
|---|
| 1680 |  | 
|---|
| 1681 |     // トークン情報を取得 | 
|---|
| 1682 |     GetSecInfo(sec); | 
|---|
| 1683 |  | 
|---|
| 1684 |     return true; | 
|---|
| 1685 | } | 
|---|
| 1686 |  | 
|---|
| 1687 | // セキュアデバイスを閉じる | 
|---|
| 1688 | void CloseSec(SECURE *sec) | 
|---|
| 1689 | { | 
|---|
| 1690 |     // 引数チェック | 
|---|
| 1691 |     if (sec == NULL) | 
|---|
| 1692 |     { | 
|---|
| 1693 |         return; | 
|---|
| 1694 |     } | 
|---|
| 1695 |  | 
|---|
| 1696 |     // ログアウトする | 
|---|
| 1697 |     LogoutSec(sec); | 
|---|
| 1698 |  | 
|---|
| 1699 |     // セッションを閉じる | 
|---|
| 1700 |     CloseSecSession(sec); | 
|---|
| 1701 |  | 
|---|
| 1702 |     // トークン情報を解放 | 
|---|
| 1703 |     FreeSecInfo(sec); | 
|---|
| 1704 |  | 
|---|
| 1705 |     // スロットリストメモリの解放 | 
|---|
| 1706 |     if (sec->SlotIdList != NULL) | 
|---|
| 1707 |     { | 
|---|
| 1708 |         Free(sec->SlotIdList); | 
|---|
| 1709 |         sec->SlotIdList = NULL; | 
|---|
| 1710 |     } | 
|---|
| 1711 |  | 
|---|
| 1712 |     // モジュールのアンロード | 
|---|
| 1713 |     FreeSecModule(sec); | 
|---|
| 1714 |  | 
|---|
| 1715 |     // メモリ解放 | 
|---|
| 1716 |     DeleteLock(sec->lock); | 
|---|
| 1717 |     Free(sec); | 
|---|
| 1718 | } | 
|---|
| 1719 |  | 
|---|
| 1720 | // セキュアデバイスを開く | 
|---|
| 1721 | SECURE *OpenSec(UINT id) | 
|---|
| 1722 | { | 
|---|
| 1723 |     SECURE_DEVICE *dev = GetSecureDevice(id); | 
|---|
| 1724 |     SECURE *sec; | 
|---|
| 1725 |     UINT err; | 
|---|
| 1726 |  | 
|---|
| 1727 |     if (dev == NULL) | 
|---|
| 1728 |     { | 
|---|
| 1729 |         return NULL; | 
|---|
| 1730 |     } | 
|---|
| 1731 |  | 
|---|
| 1732 |     sec = ZeroMalloc(sizeof(SECURE)); | 
|---|
| 1733 |  | 
|---|
| 1734 |     sec->lock = NewLock(); | 
|---|
| 1735 |     sec->Error = SEC_ERROR_NOERROR; | 
|---|
| 1736 |     sec->Dev = dev; | 
|---|
| 1737 |  | 
|---|
| 1738 |     // ePass かどうか取得する | 
|---|
| 1739 |     if (SearchStrEx(dev->DeviceName, "epass", 0, false) != INFINITE) | 
|---|
| 1740 |     { | 
|---|
| 1741 |         sec->IsEPass1000 = true; | 
|---|
| 1742 |     } | 
|---|
| 1743 |  | 
|---|
| 1744 |     // モジュールのロード | 
|---|
| 1745 |     if (LoadSecModule(sec) == false) | 
|---|
| 1746 |     { | 
|---|
| 1747 |         CloseSec(sec); | 
|---|
| 1748 |         return NULL; | 
|---|
| 1749 |     } | 
|---|
| 1750 |  | 
|---|
| 1751 |     // スロット一覧の取得 | 
|---|
| 1752 |     sec->NumSlot = 0; | 
|---|
| 1753 |     if ((err = sec->Api->C_GetSlotList(true, NULL, &sec->NumSlot)) != CKR_OK || sec->NumSlot == 0) | 
|---|
| 1754 |     { | 
|---|
| 1755 |         // 失敗 | 
|---|
| 1756 |         FreeSecModule(sec); | 
|---|
| 1757 |         CloseSec(sec); | 
|---|
| 1758 |         return NULL; | 
|---|
| 1759 |     } | 
|---|
| 1760 |  | 
|---|
| 1761 |     sec->SlotIdList = (UINT *)ZeroMalloc(sizeof(UINT *) * sec->NumSlot); | 
|---|
| 1762 |  | 
|---|
| 1763 |     if (sec->Api->C_GetSlotList(TRUE, sec->SlotIdList, &sec->NumSlot) != CKR_OK) | 
|---|
| 1764 |     { | 
|---|
| 1765 |         // 失敗 | 
|---|
| 1766 |         Free(sec->SlotIdList); | 
|---|
| 1767 |         sec->SlotIdList = NULL; | 
|---|
| 1768 |         FreeSecModule(sec); | 
|---|
| 1769 |         CloseSec(sec); | 
|---|
| 1770 |         return NULL; | 
|---|
| 1771 |     } | 
|---|
| 1772 |  | 
|---|
| 1773 |     return sec; | 
|---|
| 1774 | } | 
|---|
| 1775 |  | 
|---|
| 1776 | // セキュアデバイスのモジュールをロードする | 
|---|
| 1777 | bool LoadSecModule(SECURE *sec) | 
|---|
| 1778 | { | 
|---|
| 1779 |     bool ret = false; | 
|---|
| 1780 |     // 引数チェック | 
|---|
| 1781 |     if (sec == NULL) | 
|---|
| 1782 |     { | 
|---|
| 1783 |         return false; | 
|---|
| 1784 |     } | 
|---|
| 1785 |  | 
|---|
| 1786 | #ifdef  OS_WIN32 | 
|---|
| 1787 |     ret = Win32LoadSecModule(sec); | 
|---|
| 1788 | #endif  // OS_WIN32 | 
|---|
| 1789 |  | 
|---|
| 1790 |     // 初期化 | 
|---|
| 1791 |     if (sec->Api->C_Initialize(NULL) != CKR_OK) | 
|---|
| 1792 |     { | 
|---|
| 1793 |         // 初期化失敗 | 
|---|
| 1794 |         FreeSecModule(sec); | 
|---|
| 1795 |         return false; | 
|---|
| 1796 |     } | 
|---|
| 1797 |  | 
|---|
| 1798 |     sec->Initialized = true; | 
|---|
| 1799 |  | 
|---|
| 1800 |     return ret; | 
|---|
| 1801 | } | 
|---|
| 1802 |  | 
|---|
| 1803 | // セキュアデバイスのモジュールをアンロードする | 
|---|
| 1804 | void FreeSecModule(SECURE *sec) | 
|---|
| 1805 | { | 
|---|
| 1806 |     // 引数チェック | 
|---|
| 1807 |     if (sec == NULL) | 
|---|
| 1808 |     { | 
|---|
| 1809 |         return; | 
|---|
| 1810 |     } | 
|---|
| 1811 |  | 
|---|
| 1812 |     if (sec->Initialized) | 
|---|
| 1813 |     { | 
|---|
| 1814 |         // 初期化済みなので解放する | 
|---|
| 1815 |         sec->Api->C_Finalize(NULL); | 
|---|
| 1816 |         sec->Initialized = false; | 
|---|
| 1817 |     } | 
|---|
| 1818 |  | 
|---|
| 1819 | #ifdef  OS_WIN32 | 
|---|
| 1820 |     Win32FreeSecModule(sec); | 
|---|
| 1821 | #endif  // OS_WIN32 | 
|---|
| 1822 |  | 
|---|
| 1823 | } | 
|---|
| 1824 |  | 
|---|
| 1825 |  | 
|---|
| 1826 | // セキュアデバイスを取得する | 
|---|
| 1827 | SECURE_DEVICE *GetSecureDevice(UINT id) | 
|---|
| 1828 | { | 
|---|
| 1829 |     UINT i; | 
|---|
| 1830 |  | 
|---|
| 1831 |     if (id == 0) | 
|---|
| 1832 |     { | 
|---|
| 1833 |         return NULL; | 
|---|
| 1834 |     } | 
|---|
| 1835 |  | 
|---|
| 1836 |     for (i = 0;i < LIST_NUM(SecureDeviceList);i++) | 
|---|
| 1837 |     { | 
|---|
| 1838 |         SECURE_DEVICE *dev = LIST_DATA(SecureDeviceList, i); | 
|---|
| 1839 |  | 
|---|
| 1840 |         if (dev->Id == id) | 
|---|
| 1841 |         { | 
|---|
| 1842 |             return dev; | 
|---|
| 1843 |         } | 
|---|
| 1844 |     } | 
|---|
| 1845 |  | 
|---|
| 1846 |     return NULL; | 
|---|
| 1847 | } | 
|---|
| 1848 |  | 
|---|
| 1849 | // セキュアデバイスの ID を確認する | 
|---|
| 1850 | bool CheckSecureDeviceId(UINT id) | 
|---|
| 1851 | { | 
|---|
| 1852 |     UINT i; | 
|---|
| 1853 |  | 
|---|
| 1854 |     for (i = 0;i < LIST_NUM(SecureDeviceList);i++) | 
|---|
| 1855 |     { | 
|---|
| 1856 |         SECURE_DEVICE *dev = LIST_DATA(SecureDeviceList, i); | 
|---|
| 1857 |  | 
|---|
| 1858 |         if (dev->Id == id) | 
|---|
| 1859 |         { | 
|---|
| 1860 |             return true; | 
|---|
| 1861 |         } | 
|---|
| 1862 |     } | 
|---|
| 1863 |  | 
|---|
| 1864 |     return false; | 
|---|
| 1865 | } | 
|---|
| 1866 |  | 
|---|
| 1867 | // サポートされているデバイスリストを取得する | 
|---|
| 1868 | LIST *GetSecureDeviceList() | 
|---|
| 1869 | { | 
|---|
| 1870 |     return GetSupportedDeviceList(); | 
|---|
| 1871 | } | 
|---|
| 1872 |  | 
|---|
| 1873 | // サポートされているデバイスリストを取得する | 
|---|
| 1874 | LIST *GetSupportedDeviceList() | 
|---|
| 1875 | { | 
|---|
| 1876 |     // 参照カウントの増加 | 
|---|
| 1877 |     AddRef(SecureDeviceList->ref); | 
|---|
| 1878 |  | 
|---|
| 1879 |     return SecureDeviceList; | 
|---|
| 1880 | } | 
|---|
| 1881 |  | 
|---|
| 1882 | // 指定したデバイスがインストールされていて利用可能かどうか調べる | 
|---|
| 1883 | bool IsDeviceSupported(SECURE_DEVICE *dev) | 
|---|
| 1884 | { | 
|---|
| 1885 |     bool b = false; | 
|---|
| 1886 | #ifdef  OS_WIN32 | 
|---|
| 1887 |     b = Win32IsDeviceSupported(dev); | 
|---|
| 1888 | #endif  // OS_WIN32 | 
|---|
| 1889 |     return b; | 
|---|
| 1890 | } | 
|---|
| 1891 |  | 
|---|
| 1892 | // セキュアデバイスリストの初期化 | 
|---|
| 1893 | void InitSecureDeviceList() | 
|---|
| 1894 | { | 
|---|
| 1895 |     UINT i, num_supported_list; | 
|---|
| 1896 |     SecureDeviceList = NewList(NULL); | 
|---|
| 1897 |  | 
|---|
| 1898 |     num_supported_list = sizeof(SupportedList) / sizeof(SECURE_DEVICE); | 
|---|
| 1899 |     for (i = 0; i < num_supported_list;i++) | 
|---|
| 1900 |     { | 
|---|
| 1901 |         SECURE_DEVICE *dev = &SupportedList[i]; | 
|---|
| 1902 |  | 
|---|
| 1903 |         // サポートチェック | 
|---|
| 1904 |         if (IsDeviceSupported(dev)) | 
|---|
| 1905 |         { | 
|---|
| 1906 |             // サポートされているのでリストに追加 | 
|---|
| 1907 |             Add(SecureDeviceList, dev); | 
|---|
| 1908 |         } | 
|---|
| 1909 |     } | 
|---|
| 1910 | } | 
|---|
| 1911 |  | 
|---|
| 1912 | // テストメイン処理 | 
|---|
| 1913 | void TestSecMain(SECURE *sec) | 
|---|
| 1914 | { | 
|---|
| 1915 |     char *test_str = "SoftEther UT-VPN"; | 
|---|
| 1916 |     K *public_key, *private_key; | 
|---|
| 1917 |     // 引数チェック | 
|---|
| 1918 |     if (sec == NULL) | 
|---|
| 1919 |     { | 
|---|
| 1920 |         return; | 
|---|
| 1921 |     } | 
|---|
| 1922 |  | 
|---|
| 1923 |     Print("test_str: \"%s\"\n", test_str); | 
|---|
| 1924 |  | 
|---|
| 1925 |     Print("Writing Data...\n"); | 
|---|
| 1926 |     if (WriteSecData(sec, true, "test_str", test_str, StrLen(test_str)) == false) | 
|---|
| 1927 |     { | 
|---|
| 1928 |         Print("WriteSecData() Failed.\n"); | 
|---|
| 1929 |     } | 
|---|
| 1930 |     else | 
|---|
| 1931 |     { | 
|---|
| 1932 |         char data[MAX_SIZE]; | 
|---|
| 1933 |         Zero(data, sizeof(data)); | 
|---|
| 1934 |         Print("Reading Data...\n"); | 
|---|
| 1935 |         if (ReadSecData(sec, "test_str", data, sizeof(data)) == false) | 
|---|
| 1936 |         { | 
|---|
| 1937 |             Print("ReadSecData() Failed.\n"); | 
|---|
| 1938 |         } | 
|---|
| 1939 |         else | 
|---|
| 1940 |         { | 
|---|
| 1941 |             Print("test_str: \"%s\"\n", data); | 
|---|
| 1942 |         } | 
|---|
| 1943 |         Print("Deleting Data...\n"); | 
|---|
| 1944 |         DeleteSecData(sec, "test_str"); | 
|---|
| 1945 |     } | 
|---|
| 1946 |  | 
|---|
| 1947 |     Print("Generating Key...\n"); | 
|---|
| 1948 |     if (RsaGen(&private_key, &public_key, 1024) == false) | 
|---|
| 1949 |     { | 
|---|
| 1950 |         Print("RsaGen() Failed.\n"); | 
|---|
| 1951 |     } | 
|---|
| 1952 |     else | 
|---|
| 1953 |     { | 
|---|
| 1954 |         X *cert; | 
|---|
| 1955 |         NAME *name; | 
|---|
| 1956 |         X_SERIAL *serial; | 
|---|
| 1957 |         UINT num = 0x11220000; | 
|---|
| 1958 |  | 
|---|
| 1959 |         Print("Creating Cert...\n"); | 
|---|
| 1960 |         serial = NewXSerial(&num, sizeof(UINT)); | 
|---|
| 1961 |         name = NewName(L"Test", L"Test", L"Test", L"JP", L"Test", L"Test"); | 
|---|
| 1962 |         cert = NewRootX(public_key, private_key, name, 365, NULL); | 
|---|
| 1963 |         FreeXSerial(serial); | 
|---|
| 1964 |         if (cert == NULL) | 
|---|
| 1965 |         { | 
|---|
| 1966 |             Print("NewRootX() Failed.\n"); | 
|---|
| 1967 |         } | 
|---|
| 1968 |         else | 
|---|
| 1969 |         { | 
|---|
| 1970 |             Print("Writing Cert...\n"); | 
|---|
| 1971 |             DeleteSecData(sec, "test_cer"); | 
|---|
| 1972 |             if (WriteSecCert(sec, true, "test_cer", cert) == false) | 
|---|
| 1973 |             { | 
|---|
| 1974 |                 Print("WriteSecCert() Failed.\n"); | 
|---|
| 1975 |             } | 
|---|
| 1976 |             else | 
|---|
| 1977 |             { | 
|---|
| 1978 |                 X *x; | 
|---|
| 1979 |                 Print("Reading Cert...\n"); | 
|---|
| 1980 |                 x = ReadSecCert(sec, "test_cer"); | 
|---|
| 1981 |                 if (x == NULL) | 
|---|
| 1982 |                 { | 
|---|
| 1983 |                     Print("ReadSecCert() Failed.\n"); | 
|---|
| 1984 |                 } | 
|---|
| 1985 |                 else | 
|---|
| 1986 |                 { | 
|---|
| 1987 |                     Print("Checking two Certs... "); | 
|---|
| 1988 |                     if (CompareX(x, cert) == false) | 
|---|
| 1989 |                     { | 
|---|
| 1990 |                         Print("[FAILED]\n"); | 
|---|
| 1991 |                     } | 
|---|
| 1992 |                     else | 
|---|
| 1993 |                     { | 
|---|
| 1994 |                         Print("Ok.\n"); | 
|---|
| 1995 |                     } | 
|---|
| 1996 |                     FreeX(x); | 
|---|
| 1997 |                 } | 
|---|
| 1998 |                 if (cert != NULL) | 
|---|
| 1999 |                 { | 
|---|
| 2000 |                     X *x; | 
|---|
| 2001 |                     XToFile(cert, "cert_tmp.cer", true); | 
|---|
| 2002 |                     x = FileToX("cert_tmp.cer"); | 
|---|
| 2003 |                     if (CompareX(x, cert) == false) | 
|---|
| 2004 |                     { | 
|---|
| 2005 |                         Print("[FAILED]\n"); | 
|---|
| 2006 |                     } | 
|---|
| 2007 |                     else | 
|---|
| 2008 |                     { | 
|---|
| 2009 |                         Print("Ok.\n"); | 
|---|
| 2010 |                         Print("Writing Private Key...\n"); | 
|---|
| 2011 |                         DeleteSecKey(sec, "test_key"); | 
|---|
| 2012 |                         if (WriteSecKey(sec, true, "test_key", private_key) == false) | 
|---|
| 2013 |                         { | 
|---|
| 2014 |                             Print("WriteSecKey() Failed.\n"); | 
|---|
| 2015 |                         } | 
|---|
| 2016 |                         else | 
|---|
| 2017 |                         { | 
|---|
| 2018 |                             UCHAR sign_cpu[128]; | 
|---|
| 2019 |                             UCHAR sign_sec[128]; | 
|---|
| 2020 |                             K *pub = GetKFromX(cert); | 
|---|
| 2021 |                             Print("Ok.\n"); | 
|---|
| 2022 |                             Print("Signing Data by CPU...\n"); | 
|---|
| 2023 |                             if (RsaSign(sign_cpu, test_str, StrLen(test_str), private_key) == false) | 
|---|
| 2024 |                             { | 
|---|
| 2025 |                                 Print("RsaSign() Failed.\n"); | 
|---|
| 2026 |                             } | 
|---|
| 2027 |                             else | 
|---|
| 2028 |                             { | 
|---|
| 2029 |                                 Print("Ok.\n"); | 
|---|
| 2030 |                                 Print("sign_cpu: "); | 
|---|
| 2031 |                                 PrintBin(sign_cpu, sizeof(sign_cpu)); | 
|---|
| 2032 |                                 Print("Signing Data by %s..\n", sec->Dev->DeviceName); | 
|---|
| 2033 |                                 if (SignSec(sec, "test_key", sign_sec, test_str, StrLen(test_str)) == false) | 
|---|
| 2034 |                                 { | 
|---|
| 2035 |                                     Print("SignSec() Failed.\n"); | 
|---|
| 2036 |                                 } | 
|---|
| 2037 |                                 else | 
|---|
| 2038 |                                 { | 
|---|
| 2039 |                                     Print("Ok.\n"); | 
|---|
| 2040 |                                     Print("sign_sec: "); | 
|---|
| 2041 |                                     PrintBin(sign_sec, sizeof(sign_sec)); | 
|---|
| 2042 |                                     Print("Compare..."); | 
|---|
| 2043 |                                     if (Cmp(sign_sec, sign_cpu, sizeof(sign_cpu)) == 0) | 
|---|
| 2044 |                                     { | 
|---|
| 2045 |                                         Print("Ok.\n"); | 
|---|
| 2046 |                                         Print("Verify..."); | 
|---|
| 2047 |                                         if (RsaVerify(test_str, StrLen(test_str), | 
|---|
| 2048 |                                             sign_sec, pub) == false) | 
|---|
| 2049 |                                         { | 
|---|
| 2050 |                                             Print("[FAILED]\n"); | 
|---|
| 2051 |                                         } | 
|---|
| 2052 |                                         else | 
|---|
| 2053 |                                         { | 
|---|
| 2054 |                                             Print("Ok.\n"); | 
|---|
| 2055 |                                         } | 
|---|
| 2056 |                                     } | 
|---|
| 2057 |                                     else | 
|---|
| 2058 |                                     { | 
|---|
| 2059 |                                         Print("[DIFFIRENT]\n"); | 
|---|
| 2060 |                                     } | 
|---|
| 2061 |                                 } | 
|---|
| 2062 |                             } | 
|---|
| 2063 |                             Print("Deleting test_key...\n"); | 
|---|
| 2064 | //                          DeleteSecKey(sec, "test_key"); | 
|---|
| 2065 |                             FreeK(pub); | 
|---|
| 2066 |                         } | 
|---|
| 2067 |                     } | 
|---|
| 2068 |                     FreeX(x); | 
|---|
| 2069 |                 } | 
|---|
| 2070 |             } | 
|---|
| 2071 |             Print("Deleting Cert..\n"); | 
|---|
| 2072 | //          DeleteSecCert(sec, "test_cer"); | 
|---|
| 2073 |             FreeX(cert); | 
|---|
| 2074 |         } | 
|---|
| 2075 |         FreeName(name); | 
|---|
| 2076 |         FreeK(private_key); | 
|---|
| 2077 |         FreeK(public_key); | 
|---|
| 2078 |     } | 
|---|
| 2079 | } | 
|---|
| 2080 |  | 
|---|
| 2081 | // セキュリティデバイスのテスト | 
|---|
| 2082 | void TestSec() | 
|---|
| 2083 | { | 
|---|
| 2084 |     UINT i; | 
|---|
| 2085 |     LIST *secure_device_list; | 
|---|
| 2086 |     Print("Secure Device Test Program\n" | 
|---|
| 2087 |         "Copyright (C) 2004-2010 SoftEther Corporation. All Rights Reserved.\n\n"); | 
|---|
| 2088 |  | 
|---|
| 2089 |     // セキュアデバイスリストの取得 | 
|---|
| 2090 |     secure_device_list = GetSecureDeviceList(); | 
|---|
| 2091 |     if (secure_device_list != NULL) | 
|---|
| 2092 |     { | 
|---|
| 2093 |         UINT use_device_id; | 
|---|
| 2094 |         char tmp[MAX_SIZE]; | 
|---|
| 2095 |         Print("--- Secure Device List ---\n"); | 
|---|
| 2096 |         for (i = 0;i < LIST_NUM(secure_device_list);i++) | 
|---|
| 2097 |         { | 
|---|
| 2098 |             SECURE_DEVICE *dev = LIST_DATA(secure_device_list, i); | 
|---|
| 2099 |             Print("%2u - %s\n", dev->Id, dev->DeviceName); | 
|---|
| 2100 |         } | 
|---|
| 2101 |         Print("\n"); | 
|---|
| 2102 |         Print("Device ID >"); | 
|---|
| 2103 |         GetLine(tmp, sizeof(tmp)); | 
|---|
| 2104 |         use_device_id = ToInt(tmp); | 
|---|
| 2105 |         if (use_device_id == 0) | 
|---|
| 2106 |         { | 
|---|
| 2107 |             Print("Canceled.\n"); | 
|---|
| 2108 |         } | 
|---|
| 2109 |         else | 
|---|
| 2110 |         { | 
|---|
| 2111 |             SECURE *sec = OpenSec(use_device_id); | 
|---|
| 2112 |             Print("Opening Device...\n"); | 
|---|
| 2113 |             if (sec == NULL) | 
|---|
| 2114 |             { | 
|---|
| 2115 |                 Print("OpenSec() Failed.\n"); | 
|---|
| 2116 |             } | 
|---|
| 2117 |             else | 
|---|
| 2118 |             { | 
|---|
| 2119 |                 Print("Opening Session...\n"); | 
|---|
| 2120 |                 if (OpenSecSession(sec, 0) == false) | 
|---|
| 2121 |                 { | 
|---|
| 2122 |                     Print("OpenSecSession() Failed.\n"); | 
|---|
| 2123 |                 } | 
|---|
| 2124 |                 else | 
|---|
| 2125 |                 { | 
|---|
| 2126 |                     while (true) | 
|---|
| 2127 |                     { | 
|---|
| 2128 |                         char pin[MAX_SIZE]; | 
|---|
| 2129 |                         Print("PIN Code >"); | 
|---|
| 2130 |                         GetLine(pin, sizeof(pin)); | 
|---|
| 2131 |                         Trim(pin); | 
|---|
| 2132 |                         if (StrLen(pin) == 0) | 
|---|
| 2133 |                         { | 
|---|
| 2134 |                             Print("Canceled.\n"); | 
|---|
| 2135 |                             break; | 
|---|
| 2136 |                         } | 
|---|
| 2137 |                         else | 
|---|
| 2138 |                         { | 
|---|
| 2139 |                             Print("Login...\n"); | 
|---|
| 2140 |                             if (LoginSec(sec, pin)) | 
|---|
| 2141 |                             { | 
|---|
| 2142 |                                 TestSecMain(sec); | 
|---|
| 2143 |                                 Print("Logout...\n"); | 
|---|
| 2144 |                                 LogoutSec(sec); | 
|---|
| 2145 |                                 break; | 
|---|
| 2146 |                             } | 
|---|
| 2147 |                             else | 
|---|
| 2148 |                             { | 
|---|
| 2149 |                                 Print("Login Failed. Please Try Again.\n"); | 
|---|
| 2150 |                             } | 
|---|
| 2151 |                         } | 
|---|
| 2152 |                     } | 
|---|
| 2153 |                     Print("Closing Session...\n"); | 
|---|
| 2154 |                     CloseSecSession(sec); | 
|---|
| 2155 |                 } | 
|---|
| 2156 |                 Print("Closing Device...\n"); | 
|---|
| 2157 |                 CloseSec(sec); | 
|---|
| 2158 |             } | 
|---|
| 2159 |         } | 
|---|
| 2160 |         ReleaseList(secure_device_list); | 
|---|
| 2161 |     } | 
|---|
| 2162 |     else | 
|---|
| 2163 |     { | 
|---|
| 2164 |         Print("GetSecureDeviceList() Error.\n"); | 
|---|
| 2165 |     } | 
|---|
| 2166 | } | 
|---|
| 2167 |  | 
|---|
| 2168 | // セキュアデバイスリストの解放 | 
|---|
| 2169 | void FreeSecureDeviceList() | 
|---|
| 2170 | { | 
|---|
| 2171 |     ReleaseList(SecureDeviceList); | 
|---|
| 2172 | } | 
|---|
| 2173 |  | 
|---|
| 2174 | // セキュリティトークンモジュールの初期化 | 
|---|
| 2175 | void InitSecure() | 
|---|
| 2176 | { | 
|---|
| 2177 |     // セキュアデバイスリストの初期化 | 
|---|
| 2178 |     InitSecureDeviceList(); | 
|---|
| 2179 | } | 
|---|
| 2180 |  | 
|---|
| 2181 | // セキュリティトークンモジュールの解放 | 
|---|
| 2182 | void FreeSecure() | 
|---|
| 2183 | { | 
|---|
| 2184 |     // セキュアデバイスリストの解放 | 
|---|
| 2185 |     FreeSecureDeviceList(); | 
|---|
| 2186 | } | 
|---|
| 2187 |  | 
|---|
| 2188 |  | 
|---|