source: lab.git/Dev/utvpn/utvpn-unix-v101-7101-public/src/Mayaqua/Encrypt.c

Last change on this file was a1bae3e, checked in by mitty <mitty@…>, 12 years ago
  • copy vendor drop to trunk

git-svn-id: https://lab.mitty.jp/svn/lab/trunk@147 7d2118f6-f56c-43e7-95a2-4bb3031d96e7

  • Property mode set to 100644
File size: 61.6 KB
Line 
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// Encrypt.c
79// 暗号化および電子証明書ルーチン
80
81#define ENCRYPT_C
82
83#define __WINCRYPT_H__
84
85#include <stdio.h>
86#include <stdlib.h>
87#include <string.h>
88#include <wchar.h>
89#include <stdarg.h>
90#include <time.h>
91#include <errno.h>
92#include <openssl/ssl.h>
93#include <openssl/err.h>
94#include <openssl/rand.h>
95#include <openssl/engine.h>
96#include <openssl/bio.h>
97#include <openssl/x509.h>
98#include <openssl/pkcs7.h>
99#include <openssl/pkcs12.h>
100#include <openssl/rc4.h>
101#include <openssl/md5.h>
102#include <openssl/sha.h>
103#include <Mayaqua/Mayaqua.h>
104
105LOCK *openssl_lock = NULL;
106
107LOCK **ssl_lock_obj = NULL;
108UINT ssl_lock_num;
109static bool openssl_inited = false;
110
111// コールバック関数用
112typedef struct CB_PARAM
113{
114    char *password;
115} CB_PARAM;
116
117// 証明書が特定のディレクトリの CRL によって無効化されているかどうか確認する
118bool IsXRevoked(X *x)
119{
120    char dirname[MAX_PATH];
121    UINT i;
122    bool ret = false;
123    DIRLIST *t;
124    // 引数チェック
125    if (x == NULL)
126    {
127        return false;
128    }
129
130    GetExeDir(dirname, sizeof(dirname));
131
132    // CRL ファイルの検索
133    t = EnumDir(dirname);
134
135    for (i = 0;i < t->NumFiles;i++)
136    {
137        char *name = t->File[i]->FileName;
138        if (t->File[i]->Folder == false)
139        {
140            if (EndWith(name, ".crl"))
141            {
142                char filename[MAX_PATH];
143                X_CRL *r;
144
145                ConbinePath(filename, sizeof(filename), dirname, name);
146
147                r = FileToXCrl(filename);
148
149                if (r != NULL)
150                {
151                    if (IsXRevokedByXCrl(x, r))
152                    {
153                        ret = true;
154                    }
155
156                    FreeXCrl(r);
157                }
158            }
159        }
160    }
161
162    FreeDir(t);
163
164    return ret;
165}
166
167// 証明書が CRL によって無効化されているかどうか確認する
168bool IsXRevokedByXCrl(X *x, X_CRL *r)
169{
170#ifdef  OS_WIN32
171    X509_REVOKED tmp;
172    X509_CRL_INFO *info;
173    int index;
174    // 引数チェック
175    if (x == NULL || r == NULL)
176    {
177        return false;
178    }
179
180    Zero(&tmp, sizeof(tmp));
181    tmp.serialNumber = X509_get_serialNumber(x->x509);
182
183    info = r->Crl->crl;
184
185    if (sk_X509_REVOKED_is_sorted(info->revoked) == false)
186    {
187        sk_X509_REVOKED_sort(info->revoked);
188    }
189
190    index = sk_X509_REVOKED_find(info->revoked, &tmp);
191
192    if (index < 0)
193    {
194        return false;
195    }
196    else
197    {
198        return true;
199    }
200#else   // OS_WIN32
201    return false;
202#endif  // OS_WIN32
203}
204
205// CRL の解放
206void FreeXCrl(X_CRL *r)
207{
208    // 引数チェック
209    if (r == NULL)
210    {
211        return;
212    }
213
214    X509_CRL_free(r->Crl);
215
216    Free(r);
217}
218
219// ファイルを CRL に変換
220X_CRL *FileToXCrl(char *filename)
221{
222    wchar_t *filename_w = CopyStrToUni(filename);
223    X_CRL *ret = FileToXCrlW(filename_w);
224
225    Free(filename_w);
226
227    return ret;
228}
229X_CRL *FileToXCrlW(wchar_t *filename)
230{
231    BUF *b;
232    X_CRL *r;
233    // 引数チェック
234    if (filename == NULL)
235    {
236        return NULL;
237    }
238
239    b = ReadDumpW(filename);
240    if (b == NULL)
241    {
242        return NULL;
243    }
244
245    r = BufToXCrl(b);
246
247    FreeBuf(b);
248
249    return r;
250}
251
252// バッファを CRL に変換
253X_CRL *BufToXCrl(BUF *b)
254{
255    X_CRL *r;
256    X509_CRL *x509crl;
257    BIO *bio;
258    // 引数チェック
259    if (b == NULL)
260    {
261        return NULL;
262    }
263
264    bio = BufToBio(b);
265    if (bio == NULL)
266    {
267        return NULL;
268    }
269
270    x509crl = NULL;
271
272    if (d2i_X509_CRL_bio(bio, &x509crl) == NULL || x509crl == NULL)
273    {
274        FreeBio(bio);
275        return NULL;
276    }
277
278    r = ZeroMalloc(sizeof(X_CRL));
279    r->Crl = x509crl;
280
281    FreeBio(bio);
282
283    return r;
284}
285
286// バッファを公開鍵に変換
287K *RsaBinToPublic(void *data, UINT size)
288{
289    RSA *rsa;
290    K *k;
291    BIO *bio;
292    // 引数チェック
293    if (data == NULL || size < 4)
294    {
295        return NULL;
296    }
297
298    rsa = RSA_new();
299
300    if (rsa->e != NULL)
301    {
302        BN_free(rsa->e);
303    }
304
305    rsa->e = BN_new();
306    BN_set_word(rsa->e, RSA_F4);
307
308    if (rsa->n != NULL)
309    {
310        BN_free(rsa->n);
311    }
312
313    rsa->n = BinToBigNum(data, size);
314
315    bio = NewBio();
316    Lock(openssl_lock);
317    {
318        i2d_RSA_PUBKEY_bio(bio, rsa);
319    }
320    Unlock(openssl_lock);
321    BIO_seek(bio, 0);
322    k = BioToK(bio, false, false, NULL);
323    FreeBio(bio);
324
325    RSA_free(rsa);
326
327    return k;
328}
329
330// 公開鍵をバッファに変換
331BUF *RsaPublicToBuf(K *k)
332{
333    BUF *b;
334    // 引数チェック
335    if (k == NULL || k->pkey == NULL || k->pkey->pkey.rsa == NULL
336        || k->pkey->pkey.rsa->n == NULL)
337    {
338        return NULL;
339    }
340
341    b = BigNumToBuf(k->pkey->pkey.rsa->n);
342    if (b == NULL)
343    {
344        return NULL;
345    }
346
347    return b;
348}
349
350// 公開鍵をバイナリに変換
351void RsaPublicToBin(K *k, void *data)
352{
353    BUF *b;
354    // 引数チェック
355    if (k == NULL || k->pkey == NULL || k->pkey->pkey.rsa == NULL
356        || k->pkey->pkey.rsa->n == NULL || data == NULL)
357    {
358        return;
359    }
360
361    b = BigNumToBuf(k->pkey->pkey.rsa->n);
362    if (b == NULL)
363    {
364        return;
365    }
366
367    Copy(data, b->Buf, b->Size);
368
369    FreeBuf(b);
370}
371
372// 公開鍵サイズの取得
373UINT RsaPublicSize(K *k)
374{
375    BUF *b;
376    UINT ret;
377    // 引数チェック
378    if (k == NULL || k->pkey == NULL || k->pkey->pkey.rsa == NULL
379        || k->pkey->pkey.rsa->n == NULL)
380    {
381        return 0;
382    }
383
384    b = BigNumToBuf(k->pkey->pkey.rsa->n);
385    if (b == NULL)
386    {
387        return 0;
388    }
389
390    ret = b->Size;
391
392    FreeBuf(b);
393
394    return ret;
395}
396
397// ポインタを 32 ビットにハッシュする
398UINT HashPtrToUINT(void *p)
399{
400    UCHAR hash_data[MD5_SIZE];
401    UINT ret;
402    // 引数チェック
403    if (p == NULL)
404    {
405        return 0;
406    }
407
408    Hash(hash_data, &p, sizeof(p), false);
409
410    Copy(&ret, hash_data, sizeof(ret));
411
412    return ret;
413}
414
415// NAME のコピー
416NAME *CopyName(NAME *n)
417{
418    // 引数チェック
419    if (n == NULL)
420    {
421        return NULL;
422    }
423
424    return NewName(n->CommonName, n->Organization, n->Unit,
425        n->Country, n->State, n->Local);
426}
427
428// バイナリを BIGNUM に変換
429BIGNUM *BinToBigNum(void *data, UINT size)
430{
431    BIGNUM *bn;
432    // 引数チェック
433    if (data == NULL)
434    {
435        return NULL;
436    }
437
438    bn = BN_new();
439    BN_bin2bn(data, size, bn);
440
441    return bn;
442}
443
444// バッファを BIGNUM に変換
445BIGNUM *BufToBigNum(BUF *b)
446{
447    if (b == NULL)
448    {
449        return NULL;
450    }
451
452    return BinToBigNum(b->Buf, b->Size);
453}
454
455// BIGNUM をバッファに変換
456BUF *BigNumToBuf(BIGNUM *bn)
457{
458    UINT size;
459    UCHAR *tmp;
460    BUF *b;
461    // 引数チェック
462    if (bn == NULL)
463    {
464        return NULL;
465    }
466
467    size = BN_num_bytes(bn);
468    tmp = ZeroMalloc(size);
469    BN_bn2bin(bn, tmp);
470
471    b = NewBuf();
472    WriteBuf(b, tmp, size);
473    Free(tmp);
474
475    SeekBuf(b, 0, 0);
476
477    return b;
478}
479
480// OpenSSL のロックの初期化
481void OpenSSL_InitLock()
482{
483    UINT i;
484
485    // ロックオブジェクトの初期化
486    ssl_lock_num = CRYPTO_num_locks();
487    ssl_lock_obj = Malloc(sizeof(LOCK *) * ssl_lock_num);
488    for (i = 0;i < ssl_lock_num;i++)
489    {
490        ssl_lock_obj[i] = NewLock();
491    }
492
493    // ロック関数の設定
494    CRYPTO_set_locking_callback(OpenSSL_Lock);
495    CRYPTO_set_id_callback(OpenSSL_Id);
496}
497
498// OpenSSL のロックの解放
499void OpenSSL_FreeLock()
500{
501    UINT i;
502
503    for (i = 0;i < ssl_lock_num;i++)
504    {
505        DeleteLock(ssl_lock_obj[i]);
506    }
507    Free(ssl_lock_obj);
508    ssl_lock_obj = NULL;
509
510    CRYPTO_set_locking_callback(NULL);
511    CRYPTO_set_id_callback(NULL);
512}
513
514// OpenSSL のロック関数
515void OpenSSL_Lock(int mode, int n, const char *file, int line)
516{
517    LOCK *lock = ssl_lock_obj[n];
518
519    if (mode & CRYPTO_LOCK)
520    {
521        // ロック
522        Lock(lock);
523    }
524    else
525    {
526        // ロック解除
527        Unlock(lock);
528    }
529}
530
531// スレッド ID の返却
532unsigned long OpenSSL_Id(void)
533{
534    return (unsigned long)ThreadId();
535}
536
537// 証明書の表示名を取得
538void GetPrintNameFromX(wchar_t *str, UINT size, X *x)
539{
540    // 引数チェック
541    if (x == NULL || str == NULL)
542    {
543        return;
544    }
545
546    GetPrintNameFromName(str, size, x->subject_name);
547}
548void GetPrintNameFromXA(char *str, UINT size, X *x)
549{
550    wchar_t tmp[MAX_SIZE];
551    // 引数チェック
552    if (str == NULL || x == NULL)
553    {
554        return;
555    }
556
557    GetPrintNameFromX(tmp, sizeof(tmp), x);
558
559    UniToStr(str, size, tmp);
560}
561void GetAllNameFromXEx(wchar_t *str, UINT size, X *x)
562{
563    // 引数チェック
564    if (x == NULL || str == NULL)
565    {
566        return;
567    }
568
569    GetAllNameFromNameEx(str, size, x->subject_name);
570}
571void GetAllNameFromXExA(char *str, UINT size, X *x)
572{
573    wchar_t tmp[MAX_SIZE];
574    // 引数チェック
575    if (str == NULL || x == NULL)
576    {
577        return;
578    }
579
580    GetAllNameFromXEx(tmp, sizeof(tmp), x);
581
582    UniToStr(str, size, tmp);
583}
584
585// NAME から表示名を取得
586void GetPrintNameFromName(wchar_t *str, UINT size, NAME *name)
587{
588    // 引数チェック
589    if (str == NULL || name == NULL)
590    {
591        return;
592    }
593
594    if (name->CommonName != NULL)
595    {
596        UniStrCpy(str, size, name->CommonName);
597    }
598    else if (name->Organization != NULL)
599    {
600        UniStrCpy(str, size, name->Organization);
601    }
602    else if (name->Unit != NULL)
603    {
604        UniStrCpy(str, size, name->Unit);
605    }
606    else if (name->State != NULL)
607    {
608        UniStrCpy(str, size, name->State);
609    }
610    else if (name->Local != NULL)
611    {
612        UniStrCpy(str, size, name->Local);
613    }
614    else if (name->Country != NULL)
615    {
616        UniStrCpy(str, size, name->Country);
617    }
618    else
619    {
620        UniStrCpy(str, size, L"untitled");
621    }
622}
623
624// 証明書からすべての名前文字列を取得
625void GetAllNameFromX(wchar_t *str, UINT size, X *x)
626{
627    UCHAR md5[MD5_SIZE], sha1[SHA1_SIZE];
628    char tmp1[MD5_SIZE * 3 + 8], tmp2[SHA1_SIZE * 3 + 8];
629    wchar_t tmp3[sizeof(tmp1) + sizeof(tmp2) + 64];
630    // 引数チェック
631    if (str == NULL || x == NULL)
632    {
633        return;
634    }
635
636    GetAllNameFromName(str, size, x->subject_name);
637
638    if (x->serial != NULL && x->serial->size >= 1)
639    {
640        char tmp[128];
641        wchar_t tmp2[128];
642
643        BinToStr(tmp, sizeof(tmp), x->serial->data, x->serial->size);
644        UniFormat(tmp2, sizeof(tmp2), L", SERIAL=\"%S\"", tmp);
645
646        UniStrCat(str, size, tmp2);
647    }
648
649    // ダイジェスト値
650    GetXDigest(x, md5, false);
651    GetXDigest(x, sha1, true);
652
653    BinToStr(tmp1, sizeof(tmp1), md5, MD5_SIZE);
654    BinToStr(tmp2, sizeof(tmp2), sha1, SHA1_SIZE);
655
656    UniFormat(tmp3, sizeof(tmp3), L" (Digest: MD5=\"%S\", SHA1=\"%S\")", tmp1, tmp2);
657    UniStrCat(str, size, tmp3);
658}
659void GetAllNameFromA(char *str, UINT size, X *x)
660{
661    wchar_t tmp[MAX_SIZE];
662    // 引数チェック
663    if (str == NULL || x == NULL)
664    {
665        return;
666    }
667
668    GetAllNameFromX(tmp, sizeof(tmp), x);
669    UniToStr(str, size, tmp);
670}
671
672// NAME からすべての名前文字列を取得
673void GetAllNameFromName(wchar_t *str, UINT size, NAME *name)
674{
675    // 引数チェック
676    if (str == NULL || name == NULL)
677    {
678        return;
679    }
680
681    UniStrCpy(str, size, L"");
682    if (name->CommonName != NULL)
683    {
684        UniFormat(str, size, L"%sCN=%s, ", str, name->CommonName);
685    }
686    if (name->Organization != NULL)
687    {
688        UniFormat(str, size, L"%sO=%s, ", str, name->Organization);
689    }
690    if (name->Unit != NULL)
691    {
692        UniFormat(str, size, L"%sOU=%s, ", str, name->Unit);
693    }
694    if (name->State != NULL)
695    {
696        UniFormat(str, size, L"%sS=%s, ", str, name->State);
697    }
698    if (name->Local != NULL)
699    {
700        UniFormat(str, size, L"%sL=%s, ", str, name->Local);
701    }
702    if (name->Country != NULL)
703    {
704        UniFormat(str, size, L"%sC=%s, ", str, name->Country);
705    }
706
707    if (UniStrLen(str) >= 3)
708    {
709        UINT len = UniStrLen(str);
710        if (str[len - 2] == L',' &&
711            str[len - 1] == L' ')
712        {
713            str[len - 2] = 0;
714        }
715    }
716}
717void GetAllNameFromNameEx(wchar_t *str, UINT size, NAME *name)
718{
719    // 引数チェック
720    if (str == NULL || name == NULL)
721    {
722        return;
723    }
724
725    UniStrCpy(str, size, L"");
726    if (name->CommonName != NULL)
727    {
728        UniFormat(str, size, L"%s%s, ", str, name->CommonName);
729    }
730    if (name->Organization != NULL)
731    {
732        UniFormat(str, size, L"%s%s, ", str, name->Organization);
733    }
734    if (name->Unit != NULL)
735    {
736        UniFormat(str, size, L"%s%s, ", str, name->Unit);
737    }
738    if (name->State != NULL)
739    {
740        UniFormat(str, size, L"%s%s, ", str, name->State);
741    }
742    if (name->Local != NULL)
743    {
744        UniFormat(str, size, L"%s%s, ", str, name->Local);
745    }
746    if (name->Country != NULL)
747    {
748        UniFormat(str, size, L"%s%s, ", str, name->Country);
749    }
750
751    if (UniStrLen(str) >= 3)
752    {
753        UINT len = UniStrLen(str);
754        if (str[len - 2] == L',' &&
755            str[len - 1] == L' ')
756        {
757            str[len - 2] = 0;
758        }
759    }
760}
761
762// 鍵のクローン
763K *CloneK(K *k)
764{
765    BUF *b;
766    K *ret;
767    // 引数チェック
768    if (k == NULL)
769    {
770        return NULL;
771    }
772
773    b = KToBuf(k, false, NULL);
774    if (b == NULL)
775    {
776        return NULL;
777    }
778
779    ret = BufToK(b, k->private_key, false, NULL);
780    FreeBuf(b);
781
782    return ret;
783}
784
785// 証明書のクローン
786X *CloneX(X *x)
787{
788    BUF *b;
789    X *ret;
790    // 引数チェック
791    if (x == NULL)
792    {
793        return NULL;
794    }
795
796    b = XToBuf(x, false);
797    if (b == NULL)
798    {
799        return NULL;
800    }
801
802    ret = BufToX(b, false);
803    FreeBuf(b);
804
805    return ret;
806}
807
808// P12 を生成する
809P12 *NewP12(X *x, K *k, char *password)
810{
811    PKCS12 *pkcs12;
812    P12 *p12;
813    // 引数チェック
814    if (x == NULL || k == NULL)
815    {
816        return false;
817    }
818    if (password && StrLen(password) == 0)
819    {
820        password = NULL;
821    }
822
823    Lock(openssl_lock);
824    {
825        pkcs12 = PKCS12_create(password, NULL, k->pkey, x->x509, NULL, 0, 0, 0, 0, 0);
826        if (pkcs12 == NULL)
827        {
828            Unlock(openssl_lock);
829            return NULL;
830        }
831    }
832    Unlock(openssl_lock);
833
834    p12 = PKCS12ToP12(pkcs12);
835
836    return p12;
837}
838
839// P12 が暗号化されているかどうかチェックする
840bool IsEncryptedP12(P12 *p12)
841{
842    X *x;
843    K *k;
844    // 引数チェック
845    if (p12 == NULL)
846    {
847        return false;
848    }
849
850    if (ParseP12(p12, &x, &k, NULL) == true)
851    {
852        FreeX(x);
853        FreeK(k);
854        return false;
855    }
856
857    return true;
858}
859
860// P12 から X と K を取り出す
861bool ParseP12(P12 *p12, X **x, K **k, char *password)
862{
863    EVP_PKEY *pkey;
864    X509 *x509;
865    // 引数チェック
866    if (p12 == NULL || x == NULL || k == NULL)
867    {
868        return false;
869    }
870    if (password && StrLen(password) == 0)
871    {
872        password = NULL;
873    }
874    if (password == NULL)
875    {
876        password = "";
877    }
878
879    // パスワード確認
880    Lock(openssl_lock);
881    {
882        if (PKCS12_verify_mac(p12->pkcs12, password, -1) == false &&
883            PKCS12_verify_mac(p12->pkcs12, NULL, -1) == false)
884        {
885            Unlock(openssl_lock);
886            return false;
887        }
888    }
889    Unlock(openssl_lock);
890
891    // 抽出
892    Lock(openssl_lock);
893    {
894        if (PKCS12_parse(p12->pkcs12, password, &pkey, &x509, NULL) == false)
895        {
896            if (PKCS12_parse(p12->pkcs12, NULL, &pkey, &x509, NULL) == false)
897            {
898                Unlock(openssl_lock);
899                return false;
900            }
901        }
902    }
903    Unlock(openssl_lock);
904
905    // 変換
906    *x = X509ToX(x509);
907
908    if (*x == NULL)
909    {
910        FreePKey(pkey);
911        return false;
912    }
913
914    *k = ZeroMalloc(sizeof(K));
915    (*k)->private_key = true;
916    (*k)->pkey = pkey;
917
918    return true;
919}
920
921// P12 をファイルに書き出す
922bool P12ToFile(P12 *p12, char *filename)
923{
924    wchar_t *filename_w = CopyStrToUni(filename);
925    bool ret = P12ToFileW(p12, filename_w);
926
927    return ret;
928}
929bool P12ToFileW(P12 *p12, wchar_t *filename)
930{
931    BUF *b;
932    // 引数チェック
933    if (p12 == NULL || filename == NULL)
934    {
935        return false;
936    }
937
938    b = P12ToBuf(p12);
939    if (b == NULL)
940    {
941        return false;
942    }
943
944    if (DumpBufW(b, filename) == false)
945    {
946        FreeBuf(b);
947        return false;
948    }
949
950    FreeBuf(b);
951
952    return true;
953}
954
955// ファイルから P12 を読み込む
956P12 *FileToP12(char *filename)
957{
958    wchar_t *filename_w = CopyStrToUni(filename);
959    P12 *ret = FileToP12W(filename_w);
960
961    Free(filename_w);
962
963    return ret;
964}
965P12 *FileToP12W(wchar_t *filename)
966{
967    BUF *b;
968    P12 *p12;
969    // 引数チェック
970    if (filename == NULL)
971    {
972        return NULL;
973    }
974
975    b = ReadDumpW(filename);
976    if (b == NULL)
977    {
978        return NULL;
979    }
980
981    p12 = BufToP12(b);
982    FreeBuf(b);
983
984    return p12;
985}
986
987// P12 の解放
988void FreeP12(P12 *p12)
989{
990    // 引数チェック
991    if (p12 == NULL)
992    {
993        return;
994    }
995
996    FreePKCS12(p12->pkcs12);
997    Free(p12);
998}
999
1000// PKCS12 の解放
1001void FreePKCS12(PKCS12 *pkcs12)
1002{
1003    // 引数チェック
1004    if (pkcs12 == NULL)
1005    {
1006        return;
1007    }
1008
1009    PKCS12_free(pkcs12);
1010}
1011
1012// P12 を BUF に変換する
1013BUF *P12ToBuf(P12 *p12)
1014{
1015    BIO *bio;
1016    BUF *buf;
1017    // 引数チェック
1018    if (p12 == NULL)
1019    {
1020        return NULL;
1021    }
1022
1023    bio = P12ToBio(p12);
1024    if (bio == NULL)
1025    {
1026        return NULL;
1027    }
1028
1029    buf = BioToBuf(bio);
1030    FreeBio(bio);
1031
1032    SeekBuf(buf, 0, 0);
1033
1034    return buf;
1035}
1036
1037// P12 を BIO に変換する
1038BIO *P12ToBio(P12 *p12)
1039{
1040    BIO *bio;
1041    // 引数チェック
1042    if (p12 == NULL)
1043    {
1044        return NULL;
1045    }
1046
1047    bio = NewBio();
1048    Lock(openssl_lock);
1049    {
1050        i2d_PKCS12_bio(bio, p12->pkcs12);
1051    }
1052    Unlock(openssl_lock);
1053
1054    return bio;
1055}
1056
1057// BUF から P12 を読み込む
1058P12 *BufToP12(BUF *b)
1059{
1060    P12 *p12;
1061    BIO *bio;
1062    // 引数チェック
1063    if (b == NULL)
1064    {
1065        return NULL;
1066    }
1067
1068    bio = BufToBio(b);
1069    if (bio == NULL)
1070    {
1071        return NULL;
1072    }
1073
1074    p12 = BioToP12(bio);
1075    FreeBio(bio);
1076
1077    return p12;
1078}
1079
1080// BIO から P12 を読み込む
1081P12 *BioToP12(BIO *bio)
1082{
1083    PKCS12 *pkcs12;
1084    // 引数チェック
1085    if (bio == NULL)
1086    {
1087        return NULL;
1088    }
1089
1090    // 変換
1091    Lock(openssl_lock);
1092    {
1093        pkcs12 = d2i_PKCS12_bio(bio, NULL);
1094    }
1095    Unlock(openssl_lock);
1096    if (pkcs12 == NULL)
1097    {
1098        // 失敗
1099        return NULL;
1100    }
1101
1102    return PKCS12ToP12(pkcs12);
1103}
1104
1105// PKCS12 から P12 を生成する
1106P12 *PKCS12ToP12(PKCS12 *pkcs12)
1107{
1108    P12 *p12;
1109    // 引数チェック
1110    if (pkcs12 == NULL)
1111    {
1112        return NULL;
1113    }
1114
1115    p12 = ZeroMalloc(sizeof(P12));
1116    p12->pkcs12 = pkcs12;
1117
1118    return p12;
1119}
1120
1121// バイナリを文字列に変換する
1122char *ByteToStr(BYTE *src, UINT src_size)
1123{
1124    UINT size;
1125    char *dst;
1126    UINT i;
1127    // 引数チェック
1128    if (src == NULL)
1129    {
1130        return NULL;
1131    }
1132
1133    size = MAX(src_size * 3, 1);
1134    dst = Malloc(size);
1135    dst[size - 1] = 0;
1136    for (i = 0;i < src_size;i++)
1137    {
1138        char tmp[3];
1139        Format(tmp, sizeof(tmp), "%02x", src[i]);
1140        dst[i * 3 + 0] = tmp[0];
1141        dst[i * 3 + 1] = tmp[1];
1142        dst[i * 3 + 2] = ((i == (src_size - 1) ? 0 : ' '));
1143    }
1144
1145    return dst;
1146}
1147
1148// X_SERIAL の解放
1149void FreeXSerial(X_SERIAL *serial)
1150{
1151    // 引数チェック
1152    if (serial == NULL)
1153    {
1154        return;
1155    }
1156
1157    Free(serial->data);
1158    Free(serial);
1159}
1160
1161// X_SERIAL の比較
1162bool CompareXSerial(X_SERIAL *s1, X_SERIAL *s2)
1163{
1164    // 引数チェック
1165    if (s1 == NULL || s2 == NULL)
1166    {
1167        return false;
1168    }
1169
1170    if (s1->size != s2->size)
1171    {
1172        return false;
1173    }
1174
1175    if (Cmp(s1->data, s2->data, s1->size) != 0)
1176    {
1177        return false;
1178    }
1179
1180    return true;
1181}
1182
1183// X_SERIAL のコピー
1184X_SERIAL *CloneXSerial(X_SERIAL *src)
1185{
1186    X_SERIAL *s;
1187    // 引数チェック
1188    if (src == NULL)
1189    {
1190        return NULL;
1191    }
1192
1193    s = ZeroMalloc(sizeof(X_SERIAL));
1194    s->data = ZeroMalloc(src->size);
1195    Copy(s->data, src->data, src->size);
1196    s->size = src->size;
1197
1198    return s;
1199}
1200
1201// X_SERIAL の初期化
1202X_SERIAL *NewXSerial(void *data, UINT size)
1203{
1204    X_SERIAL *serial;
1205    UCHAR *buf = (UCHAR *)data;
1206    UINT i;
1207    // 引数チェック
1208    if (data == NULL || size == 0)
1209    {
1210        return NULL;
1211    }
1212
1213    for (i = 0;i < size;i++)
1214    {
1215        if (buf[i] != 0)
1216        {
1217            break;
1218        }
1219    }
1220    if (i == size)
1221    {
1222        i = size - 1;
1223    }
1224    buf += i;
1225
1226    serial = Malloc(sizeof(X_SERIAL));
1227    serial->size = size - i;
1228    serial->data = ZeroMalloc(size + 16);
1229    Copy(serial->data, buf, size - i);
1230
1231    return serial;
1232}
1233
1234// 2038 年 1 月 1 日までの日数を取得する
1235UINT GetDaysUntil2038()
1236{
1237    UINT64 now = SystemTime64();
1238    UINT64 target;
1239    SYSTEMTIME st;
1240
1241    Zero(&st, sizeof(st));
1242    st.wYear = 2038;
1243    st.wMonth = 1;
1244    st.wDay = 1;
1245
1246    target = SystemToUINT64(&st);
1247
1248    if (now >= target)
1249    {
1250        return 0;
1251    }
1252    else
1253    {
1254        return (UINT)((target - now) / (UINT64)(1000 * 60 * 60 * 24));
1255    }
1256}
1257
1258// X509 証明書を発行する
1259X *NewX(K *pub, K *priv, X *ca, NAME *name, UINT days, X_SERIAL *serial)
1260{
1261    X509 *x509;
1262    X *x;
1263    // 引数チェック
1264    if (pub == NULL || priv == NULL || name == NULL || ca == NULL)
1265    {
1266        return NULL;
1267    }
1268
1269    x509 = NewX509(pub, priv, ca, name, days, serial);
1270    if (x509 == NULL)
1271    {
1272        return NULL;
1273    }
1274
1275    x = X509ToX(x509);
1276
1277    if (x == NULL)
1278    {
1279        return NULL;
1280    }
1281
1282    return x;
1283}
1284
1285// ルート証明書を作成する
1286X *NewRootX(K *pub, K *priv, NAME *name, UINT days, X_SERIAL *serial)
1287{
1288    X509 *x509;
1289    X *x, *x2;
1290    // 引数チェック
1291    if (pub == NULL || priv == NULL || name == NULL)
1292    {
1293        return NULL;
1294    }
1295
1296    x509 = NewRootX509(pub, priv, name, days, serial);
1297    if (x509 == NULL)
1298    {
1299        return NULL;
1300    }
1301
1302    x = X509ToX(x509);
1303    if (x == NULL)
1304    {
1305        return NULL;
1306    }
1307
1308    x2 = CloneX(x);
1309    FreeX(x);
1310
1311    return x2;
1312}
1313
1314// X509 証明書を発行する
1315X509 *NewX509(K *pub, K *priv, X *ca, NAME *name, UINT days, X_SERIAL *serial)
1316{
1317    X509 *x509;
1318    UINT64 notBefore, notAfter;
1319    ASN1_TIME *t1, *t2;
1320    X509_NAME *subject_name, *issuer_name;
1321    // 引数チェック
1322    if (pub == NULL || name == NULL || ca == NULL)
1323    {
1324        return NULL;
1325    }
1326    if (pub->private_key != false)
1327    {
1328        return NULL;
1329    }
1330    if (priv->private_key == false)
1331    {
1332        return NULL;
1333    }
1334
1335    notBefore = SystemTime64();
1336    notAfter = notBefore + (UINT64)days * (UINT64)3600 * (UINT64)24 * (UINT64)1000;
1337
1338
1339    // X509 の作成
1340    x509 = X509_new();
1341    if (x509 == NULL)
1342    {
1343        return NULL;
1344    }
1345
1346    // 有効期限の設定
1347    t1 = X509_get_notBefore(x509);
1348    t2 = X509_get_notAfter(x509);
1349    if (!UINT64ToAsn1Time(t1, notBefore))
1350    {
1351        FreeX509(x509);
1352        return NULL;
1353    }
1354    if (!UINT64ToAsn1Time(t2, notAfter))
1355    {
1356        FreeX509(x509);
1357        return NULL;
1358    }
1359
1360    // 名前の設定
1361    subject_name = NameToX509Name(name);
1362    if (subject_name == NULL)
1363    {
1364        FreeX509(x509);
1365        return NULL;
1366    }
1367    issuer_name = X509_get_subject_name(ca->x509);
1368    if (issuer_name == NULL)
1369    {
1370        FreeX509Name(subject_name);
1371        FreeX509(x509);
1372        return NULL;
1373    }
1374
1375    X509_set_issuer_name(x509, issuer_name);
1376    X509_set_subject_name(x509, subject_name);
1377
1378    FreeX509Name(subject_name);
1379
1380    // シリアル番号の設定
1381    if (serial == NULL)
1382    {
1383        char zero = 0;
1384        ASN1_INTEGER *s = x509->cert_info->serialNumber;
1385        OPENSSL_free(s->data);
1386        s->data = OPENSSL_malloc(sizeof(char));
1387        Copy(s->data, &zero, sizeof(char));
1388        s->length = sizeof(char);
1389    }
1390    else
1391    {
1392        ASN1_INTEGER *s = x509->cert_info->serialNumber;
1393        OPENSSL_free(s->data);
1394        s->data = OPENSSL_malloc(serial->size);
1395        Copy(s->data, serial->data, serial->size);
1396        s->length = serial->size;
1397    }
1398
1399    Lock(openssl_lock);
1400    {
1401        // 公開鍵の設定
1402        X509_set_pubkey(x509, pub->pkey);
1403
1404        // 署名
1405        X509_sign(x509, priv->pkey, EVP_sha1());
1406    }
1407    Unlock(openssl_lock);
1408
1409    return x509;
1410}
1411
1412// ルート X509 証明書を作成する
1413X509 *NewRootX509(K *pub, K *priv, NAME *name, UINT days, X_SERIAL *serial)
1414{
1415    X509 *x509;
1416    UINT64 notBefore, notAfter;
1417    ASN1_TIME *t1, *t2;
1418    X509_NAME *subject_name, *issuer_name;
1419    // 引数チェック
1420    if (pub == NULL || name == NULL || priv == NULL)
1421    {
1422        return NULL;
1423    }
1424    if (days == 0)
1425    {
1426        days = 365;
1427    }
1428    if (priv->private_key == false)
1429    {
1430        return NULL;
1431    }
1432    if (pub->private_key != false)
1433    {
1434        return NULL;
1435    }
1436
1437    notBefore = SystemTime64();
1438    notAfter = notBefore + (UINT64)days * (UINT64)3600 * (UINT64)24 * (UINT64)1000;
1439
1440    // X509 の作成
1441    x509 = X509_new();
1442    if (x509 == NULL)
1443    {
1444        return NULL;
1445    }
1446
1447    // 有効期限の設定
1448    t1 = X509_get_notBefore(x509);
1449    t2 = X509_get_notAfter(x509);
1450    if (!UINT64ToAsn1Time(t1, notBefore))
1451    {
1452        FreeX509(x509);
1453        return NULL;
1454    }
1455    if (!UINT64ToAsn1Time(t2, notAfter))
1456    {
1457        FreeX509(x509);
1458        return NULL;
1459    }
1460
1461    // 名前の設定
1462    subject_name = NameToX509Name(name);
1463    if (subject_name == NULL)
1464    {
1465        FreeX509(x509);
1466        return NULL;
1467    }
1468    issuer_name = NameToX509Name(name);
1469    if (issuer_name == NULL)
1470    {
1471        FreeX509Name(subject_name);
1472        FreeX509(x509);
1473        return NULL;
1474    }
1475
1476    X509_set_issuer_name(x509, issuer_name);
1477    X509_set_subject_name(x509, subject_name);
1478
1479    FreeX509Name(subject_name);
1480    FreeX509Name(issuer_name);
1481
1482    // シリアル番号の設定
1483    if (serial == NULL)
1484    {
1485        char zero = 0;
1486        ASN1_INTEGER *s = x509->cert_info->serialNumber;
1487        OPENSSL_free(s->data);
1488        s->data = OPENSSL_malloc(sizeof(char));
1489        Copy(s->data, &zero, sizeof(char));
1490        s->length = sizeof(char);
1491    }
1492    else
1493    {
1494        ASN1_INTEGER *s = x509->cert_info->serialNumber;
1495        OPENSSL_free(s->data);
1496        s->data = OPENSSL_malloc(serial->size);
1497        Copy(s->data, serial->data, serial->size);
1498        s->length = serial->size;
1499    }
1500
1501    Lock(openssl_lock);
1502    {
1503        // 公開鍵の設定
1504        X509_set_pubkey(x509, pub->pkey);
1505
1506        // 署名
1507        X509_sign(x509, priv->pkey, EVP_sha1());
1508    }
1509    Unlock(openssl_lock);
1510
1511    return x509;
1512}
1513
1514// NAME を X509_NAME に変換
1515void *NameToX509Name(NAME *nm)
1516{
1517    X509_NAME *xn;
1518    // 引数チェック
1519    if (nm == NULL)
1520    {
1521        return NULL;
1522    }
1523
1524    xn = X509_NAME_new();
1525    if (xn == NULL)
1526    {
1527        return NULL;
1528    }
1529
1530    // エントリの追加
1531    AddX509Name(xn, NID_commonName, nm->CommonName);
1532    AddX509Name(xn, NID_organizationName, nm->Organization);
1533    AddX509Name(xn, NID_organizationalUnitName, nm->Unit);
1534    AddX509Name(xn, NID_countryName, nm->Country);
1535    AddX509Name(xn, NID_stateOrProvinceName, nm->State);
1536    AddX509Name(xn, NID_localityName, nm->Local);
1537
1538    return xn;
1539}
1540
1541// X509_NAME にエントリを追加する
1542bool AddX509Name(void *xn, int nid, wchar_t *str)
1543{
1544    X509_NAME *x509_name;
1545    UINT utf8_size;
1546    BYTE *utf8;
1547    // 引数チェック
1548    if (xn == NULL || str == NULL)
1549    {
1550        return false;
1551    }
1552
1553    // UTF-8 に変換
1554    utf8_size = CalcUniToUtf8(str);
1555    if (utf8_size == 0)
1556    {
1557        return false;
1558    }
1559    utf8 = ZeroMalloc(utf8_size + 1);
1560    UniToUtf8(utf8, utf8_size, str);
1561    utf8[utf8_size] = 0;
1562
1563    // 追加
1564    x509_name = (X509_NAME *)xn;
1565    Lock(openssl_lock);
1566    {
1567        X509_NAME_add_entry_by_NID(x509_name, nid, MBSTRING_ASC, utf8, utf8_size, -1, 0);
1568    }
1569    Unlock(openssl_lock);
1570    Free(utf8);
1571
1572    return true;
1573}
1574
1575// X509_NAME を解放
1576void FreeX509Name(void *xn)
1577{
1578    X509_NAME *x509_name;
1579    // 引数チェック
1580    if (xn == NULL)
1581    {
1582        return;
1583    }
1584
1585    x509_name = (X509_NAME *)xn;
1586    X509_NAME_free(x509_name);
1587}
1588
1589// NAME の作成
1590NAME *NewName(wchar_t *common_name, wchar_t *organization, wchar_t *unit,
1591              wchar_t *country, wchar_t *state, wchar_t *local)
1592{
1593    NAME *nm = ZeroMalloc(sizeof(NAME));
1594
1595    if (UniIsEmptyStr(common_name) == false)
1596    {
1597        nm->CommonName = CopyUniStr(common_name);
1598    }
1599
1600    if (UniIsEmptyStr(organization) == false)
1601    {
1602        nm->Organization = CopyUniStr(organization);
1603    }
1604
1605    if (UniIsEmptyStr(unit) == false)
1606    {
1607        nm->Unit = CopyUniStr(unit);
1608    }
1609
1610    if (UniIsEmptyStr(country) == false)
1611    {
1612        nm->Country = CopyUniStr(country);
1613    }
1614
1615    if (UniIsEmptyStr(state) == false)
1616    {
1617        nm->State = CopyUniStr(state);
1618    }
1619
1620    if (UniIsEmptyStr(local) == false)
1621    {
1622        nm->Local = CopyUniStr(local);
1623    }
1624
1625    return nm;
1626}
1627
1628// 証明書の有効期限を現在時刻で確認する
1629bool CheckXDateNow(X *x)
1630{
1631    // 引数チェック
1632    if (x == NULL)
1633    {
1634        return false;
1635    }
1636
1637    return CheckXDate(x, SystemTime64());
1638}
1639
1640// 証明書の有効期限を確認する
1641bool CheckXDate(X *x, UINT64 current_system_time)
1642{
1643    // 引数チェック
1644    if (x == NULL)
1645    {
1646        return false;
1647    }
1648
1649    if (x->notBefore >= current_system_time || x->notAfter <= current_system_time)
1650    {
1651        return false;
1652    }
1653    return true;
1654}
1655
1656// 証明書の有効期限情報を読み込む
1657void LoadXDates(X *x)
1658{
1659    // 引数チェック
1660    if (x == NULL)
1661    {
1662        return;
1663    }
1664
1665    x->notBefore = Asn1TimeToUINT64(x->x509->cert_info->validity->notBefore);
1666    x->notAfter = Asn1TimeToUINT64(x->x509->cert_info->validity->notAfter);
1667}
1668
1669// 64bit システム時刻を ASN1 時刻に変換する
1670bool UINT64ToAsn1Time(void *asn1_time, UINT64 t)
1671{
1672    SYSTEMTIME st;
1673    // 引数チェック
1674    if (asn1_time == NULL)
1675    {
1676        return false;
1677    }
1678
1679    UINT64ToSystem(&st, t);
1680    return SystemToAsn1Time(asn1_time, &st);
1681}
1682
1683// システム時刻を ASN1 時刻に変換する
1684bool SystemToAsn1Time(void *asn1_time, SYSTEMTIME *s)
1685{
1686    char tmp[20];
1687    ASN1_TIME *t;
1688    // 引数チェック
1689    if (asn1_time == NULL || s == NULL)
1690    {
1691        return false;
1692    }
1693
1694    if (SystemToStr(tmp, sizeof(tmp), s) == false)
1695    {
1696        return false;
1697    }
1698    t = (ASN1_TIME *)asn1_time;
1699    if (t->data == NULL || t->length < sizeof(tmp))
1700    {
1701        t->data = OPENSSL_malloc(sizeof(tmp));
1702    }
1703    StrCpy((char *)t->data, t->length, tmp);
1704    t->length = StrLen(tmp);
1705    t->type = V_ASN1_UTCTIME;
1706
1707    return true;
1708}
1709
1710// システム時刻を文字列に変換する
1711bool SystemToStr(char *str, UINT size, SYSTEMTIME *s)
1712{
1713    // 引数チェック
1714    if (str == NULL || s == NULL)
1715    {
1716        return false;
1717    }
1718
1719    Format(str, size, "%02u%02u%02u%02u%02u%02uZ",
1720        s->wYear % 100, s->wMonth, s->wDay,
1721        s->wHour, s->wMinute, s->wSecond);
1722
1723    return true;
1724}
1725
1726// ASN1 時刻を UINT64 時刻に変換する
1727UINT64 Asn1TimeToUINT64(void *asn1_time)
1728{
1729    SYSTEMTIME st;
1730    // 引数チェック
1731    if (asn1_time == NULL)
1732    {
1733        return 0;
1734    }
1735
1736    if (Asn1TimeToSystem(&st, asn1_time) == false)
1737    {
1738        return 0;
1739    }
1740    return SystemToUINT64(&st);
1741}
1742
1743// ASN1 時刻をシステム時刻に変換する
1744bool Asn1TimeToSystem(SYSTEMTIME *s, void *asn1_time)
1745{
1746    ASN1_TIME *t;
1747    // 引数チェック
1748    if (s == NULL || asn1_time == NULL)
1749    {
1750        return false;
1751    }
1752
1753    t = (ASN1_TIME *)asn1_time;
1754    if (StrToSystem(s, (char *)t->data) == false)
1755    {
1756        return false;
1757    }
1758
1759    if (t->type == V_ASN1_GENERALIZEDTIME)
1760    {
1761        LocalToSystem(s, s);
1762    }
1763
1764    return true;
1765}
1766
1767// 文字列をシステム時刻に変換する
1768bool StrToSystem(SYSTEMTIME *s, char *str)
1769{
1770    // 引数チェック
1771    if (s == NULL || str == NULL)
1772    {
1773        return false;
1774    }
1775    if (StrLen(str) != 13)
1776    {
1777        return false;
1778    }
1779    if (str[12] != 'Z')
1780    {
1781        return false;
1782    }
1783
1784    // 変換
1785    {
1786        char year[3] = {str[0], str[1], 0},
1787            month[3] = {str[2], str[3], 0},
1788            day[3] = {str[4], str[5], 0},
1789            hour[3] = {str[6], str[7], 0},
1790            minute[3] = {str[8], str[9], 0},
1791            second[3] = {str[10], str[11], 0};
1792        Zero(s, sizeof(SYSTEMTIME));
1793        s->wYear = ToInt(year);
1794        if (s->wYear >= 60)
1795        {
1796            s->wYear += 1900;
1797        }
1798        else
1799        {
1800            s->wYear += 2000;
1801        }
1802        s->wMonth = ToInt(month);
1803        s->wDay = ToInt(day);
1804        s->wHour = ToInt(hour);
1805        s->wMinute = ToInt(minute);
1806        s->wSecond = ToInt(second);
1807        NormalizeSystem(s);
1808    }
1809
1810    return true;
1811}
1812
1813// RSA 署名の検査
1814bool RsaVerify(void *data, UINT data_size, void *sign, K *k)
1815{
1816    return RsaVerifyEx(data, data_size, sign, k, 0);
1817}
1818bool RsaVerifyEx(void *data, UINT data_size, void *sign, K *k, UINT bits)
1819{
1820    UCHAR hash_data[SIGN_HASH_SIZE];
1821    UCHAR decrypt_data[SIGN_HASH_SIZE];
1822    // 引数チェック
1823    if (data == NULL || sign == NULL || k == NULL || k->private_key != false)
1824    {
1825        return false;
1826    }
1827    if (bits == 0)
1828    {
1829        bits = 1024;
1830    }
1831
1832    // データをハッシュ
1833    if (HashForSign(hash_data, sizeof(hash_data), data, data_size) == false)
1834    {
1835        return false;
1836    }
1837
1838    // 署名を解読
1839    if (RSA_public_decrypt(bits / 8, sign, decrypt_data, k->pkey->pkey.rsa, RSA_PKCS1_PADDING) <= 0)
1840    {
1841        return false;
1842    }
1843
1844    // 比較
1845    if (Cmp(decrypt_data, hash_data, sizeof(SIGN_HASH_SIZE)) != 0)
1846    {
1847        return false;
1848    }
1849
1850    return true;
1851}
1852
1853// RSA 署名
1854bool RsaSign(void *dst, void *src, UINT size, K *k)
1855{
1856    return RsaSignEx(dst, src, size, k, 0);
1857}
1858bool RsaSignEx(void *dst, void *src, UINT size, K *k, UINT bits)
1859{
1860    UCHAR hash[SIGN_HASH_SIZE];
1861    // 引数チェック
1862    if (dst == NULL || src == NULL || k == NULL || k->pkey->type != EVP_PKEY_RSA)
1863    {
1864        return false;
1865    }
1866    if (bits == 0)
1867    {
1868        bits = 1024;
1869    }
1870
1871    Zero(dst, bits / 8);
1872
1873    // ハッシュ
1874    if (HashForSign(hash, sizeof(hash), src, size) == false)
1875    {
1876        return false;
1877    }
1878
1879    // 署名
1880    if (RSA_private_encrypt(sizeof(hash), hash, dst, k->pkey->pkey.rsa, RSA_PKCS1_PADDING) <= 0)
1881    {
1882        return false;
1883    }
1884
1885    return true;
1886}
1887
1888// SHA-1 による署名データの生成
1889bool HashForSign(void *dst, UINT dst_size, void *src, UINT src_size)
1890{
1891    UCHAR *buf = (UCHAR *)dst;
1892    UCHAR sign_data[] =
1893    {
1894        0x30, 0x21, 0x30, 0x09, 0x06, 0x05, 0x2B, 0x0E,
1895        0x03, 0x02, 0x1A, 0x05, 0x00, 0x04, 0x14,
1896    };
1897    // 引数チェック
1898    if (dst == NULL || src == NULL || src_size == 0 || MIN_SIGN_HASH_SIZE > dst_size)
1899    {
1900        return false;
1901    }
1902
1903    // ヘッダ部分
1904    Copy(buf, sign_data, sizeof(sign_data));
1905
1906    // ハッシュ
1907    HashSha1(HASHED_DATA(buf), src, src_size);
1908
1909    return true;
1910}
1911
1912// RSA 公開鍵による復号化
1913bool RsaPublicDecrypt(void *dst, void *src, UINT size, K *k)
1914{
1915    void *tmp;
1916    int ret;
1917    // 引数チェック
1918    if (src == NULL || size == 0 || k == NULL)
1919    {
1920        return false;
1921    }
1922
1923    tmp = ZeroMalloc(size);
1924    Lock(openssl_lock);
1925    {
1926        ret = RSA_public_decrypt(size, src, tmp, k->pkey->pkey.rsa, RSA_NO_PADDING);
1927    }
1928    Unlock(openssl_lock);
1929    if (ret <= 0)
1930    {
1931/*      Debug("RSA Error: 0x%x\n",
1932            ERR_get_error());
1933*/      Free(tmp);
1934        return false;
1935    }
1936
1937    Copy(dst, tmp, size);
1938    Free(tmp);
1939
1940    return true;
1941}
1942
1943// RSA 秘密鍵による暗号化
1944bool RsaPrivateEncrypt(void *dst, void *src, UINT size, K *k)
1945{
1946    void *tmp;
1947    int ret;
1948    // 引数チェック
1949    if (src == NULL || size == 0 || k == NULL)
1950    {
1951        return false;
1952    }
1953
1954    tmp = ZeroMalloc(size);
1955    Lock(openssl_lock);
1956    {
1957        ret = RSA_private_encrypt(size, src, tmp, k->pkey->pkey.rsa, RSA_NO_PADDING);
1958    }
1959    Unlock(openssl_lock);
1960    if (ret <= 0)
1961    {
1962/*      Debug("RSA Error: %u\n",
1963            ERR_GET_REASON(ERR_get_error()));
1964*/      Free(tmp);
1965        return false;
1966    }
1967
1968    Copy(dst, tmp, size);
1969    Free(tmp);
1970
1971    return true;
1972}
1973
1974// RSA 秘密鍵による復号化
1975bool RsaPrivateDecrypt(void *dst, void *src, UINT size, K *k)
1976{
1977    void *tmp;
1978    int ret;
1979    // 引数チェック
1980    if (src == NULL || size == 0 || k == NULL)
1981    {
1982        return false;
1983    }
1984
1985    tmp = ZeroMalloc(size);
1986    Lock(openssl_lock);
1987    {
1988        ret = RSA_private_decrypt(size, src, tmp, k->pkey->pkey.rsa, RSA_NO_PADDING);
1989    }
1990    Unlock(openssl_lock);
1991    if (ret <= 0)
1992    {
1993        return false;
1994    }
1995
1996    Copy(dst, tmp, size);
1997    Free(tmp);
1998
1999    return true;
2000}
2001
2002// RSA 公開鍵による暗号化
2003bool RsaPublicEncrypt(void *dst, void *src, UINT size, K *k)
2004{
2005    void *tmp;
2006    int ret;
2007    // 引数チェック
2008    if (src == NULL || size == 0 || k == NULL)
2009    {
2010        return false;
2011    }
2012
2013    tmp = ZeroMalloc(size);
2014    Lock(openssl_lock);
2015    {
2016        ret = RSA_public_encrypt(size, src, tmp, k->pkey->pkey.rsa, RSA_NO_PADDING);
2017    }
2018    Unlock(openssl_lock);
2019    if (ret <= 0)
2020    {
2021        return false;
2022    }
2023
2024    Copy(dst, tmp, size);
2025    Free(tmp);
2026
2027    return true;
2028}
2029
2030// RSA 動作環境チェック
2031bool RsaCheckEx()
2032{
2033    UINT num = 20;
2034    UINT i;
2035
2036    for (i = 0;i < num;i++)
2037    {
2038        if (RsaCheck())
2039        {
2040            return true;
2041        }
2042
2043        SleepThread(100);
2044    }
2045
2046    return false;
2047}
2048bool RsaCheck()
2049{
2050    RSA *rsa;
2051    K *priv_key, *pub_key;
2052    BIO *bio;
2053    char errbuf[MAX_SIZE];
2054    UINT size = 0;
2055    UINT bit = 32;
2056    // 引数チェック
2057
2058    // 鍵生成
2059    Lock(openssl_lock);
2060    {
2061        rsa = RSA_generate_key(bit, RSA_F4, NULL, NULL);
2062    }
2063    Unlock(openssl_lock);
2064    if (rsa == NULL)
2065    {
2066        Debug("RSA_generate_key: err=%s\n", ERR_error_string(ERR_get_error(), errbuf));
2067        return false;
2068    }
2069
2070    // 秘密鍵
2071    bio = NewBio();
2072    Lock(openssl_lock);
2073    {
2074        i2d_RSAPrivateKey_bio(bio, rsa);
2075    }
2076    Unlock(openssl_lock);
2077    BIO_seek(bio, 0);
2078    priv_key = BioToK(bio, true, false, NULL);
2079    FreeBio(bio);
2080
2081    // 公開鍵
2082    bio = NewBio();
2083    Lock(openssl_lock);
2084    {
2085        i2d_RSA_PUBKEY_bio(bio, rsa);
2086    }
2087    Unlock(openssl_lock);
2088    BIO_seek(bio, 0);
2089    pub_key = BioToK(bio, false, false, NULL);
2090    FreeBio(bio);
2091
2092    RSA_free(rsa);
2093
2094    size = RsaPublicSize(pub_key);
2095
2096    if (size != ((bit + 7) / 8))
2097    {
2098        FreeK(priv_key);
2099        FreeK(pub_key);
2100
2101        return false;
2102    }
2103
2104    FreeK(priv_key);
2105    FreeK(pub_key);
2106
2107    return true;
2108}
2109
2110// RSA 鍵の生成
2111bool RsaGen(K **priv, K **pub, UINT bit)
2112{
2113    RSA *rsa;
2114    K *priv_key, *pub_key;
2115    BIO *bio;
2116    char errbuf[MAX_SIZE];
2117    UINT size = 0;
2118    // 引数チェック
2119    if (priv == NULL || pub == NULL)
2120    {
2121        return false;
2122    }
2123    if (bit == 0)
2124    {
2125        bit = 1024;
2126    }
2127
2128    // 鍵生成
2129    Lock(openssl_lock);
2130    {
2131        rsa = RSA_generate_key(bit, RSA_F4, NULL, NULL);
2132    }
2133    Unlock(openssl_lock);
2134    if (rsa == NULL)
2135    {
2136        Debug("RSA_generate_key: err=%s\n", ERR_error_string(ERR_get_error(), errbuf));
2137        return false;
2138    }
2139
2140    // 秘密鍵
2141    bio = NewBio();
2142    Lock(openssl_lock);
2143    {
2144        i2d_RSAPrivateKey_bio(bio, rsa);
2145    }
2146    Unlock(openssl_lock);
2147    BIO_seek(bio, 0);
2148    priv_key = BioToK(bio, true, false, NULL);
2149    FreeBio(bio);
2150
2151    // 公開鍵
2152    bio = NewBio();
2153    Lock(openssl_lock);
2154    {
2155        i2d_RSA_PUBKEY_bio(bio, rsa);
2156    }
2157    Unlock(openssl_lock);
2158    BIO_seek(bio, 0);
2159    pub_key = BioToK(bio, false, false, NULL);
2160    FreeBio(bio);
2161
2162    *priv = priv_key;
2163    *pub = pub_key;
2164
2165    RSA_free(rsa);
2166
2167    size = RsaPublicSize(*pub);
2168
2169    if (size != ((bit + 7) / 8))
2170    {
2171        FreeK(*priv);
2172        FreeK(*pub);
2173
2174        return RsaGen(priv, pub, bit);
2175    }
2176
2177    return true;
2178}
2179
2180// 証明書 X が証明書 x_issuer の発行者によって署名されているかどうか確認する
2181bool CheckX(X *x, X *x_issuer)
2182{
2183    K *k;
2184    bool ret;
2185    // 引数チェック
2186    if (x == NULL || x_issuer == NULL)
2187    {
2188        return false;
2189    }
2190
2191    k = GetKFromX(x_issuer);
2192    if (k == NULL)
2193    {
2194        return false;
2195    }
2196
2197    ret = CheckSignature(x, k);
2198    FreeK(k);
2199
2200    return ret;
2201}
2202
2203// 証明書 X の署名を公開鍵 K で確認する
2204bool CheckSignature(X *x, K *k)
2205{
2206    // 引数チェック
2207    if (x == NULL || k == NULL)
2208    {
2209        return false;
2210    }
2211
2212    Lock(openssl_lock);
2213    {
2214        if (X509_verify(x->x509, k->pkey) == 0)
2215        {
2216            Unlock(openssl_lock);
2217            return false;
2218        }
2219    }
2220    Unlock(openssl_lock);
2221    return true;
2222}
2223
2224// 証明書から公開鍵を取得する
2225K *GetKFromX(X *x)
2226{
2227    EVP_PKEY *pkey;
2228    K *k;
2229    // 引数チェック
2230    if (x == NULL)
2231    {
2232        return NULL;
2233    }
2234
2235    Lock(openssl_lock);
2236    {
2237        pkey = X509_get_pubkey(x->x509);
2238    }
2239    Unlock(openssl_lock);
2240    if (pkey == NULL)
2241    {
2242        return NULL;
2243    }
2244
2245    k = ZeroMalloc(sizeof(K));
2246    k->pkey = pkey;
2247
2248    return k;
2249}
2250
2251// 名前の比較
2252bool CompareName(NAME *n1, NAME *n2)
2253{
2254    // 引数チェック
2255    if (n1 == NULL || n2 == NULL)
2256    {
2257        return false;
2258    }
2259
2260    // 名前比較
2261    if (UniStrCmpi(n1->CommonName, n2->CommonName) == 0 &&
2262        UniStrCmpi(n1->Organization, n2->Organization) == 0 &&
2263        UniStrCmpi(n1->Unit, n2->Unit) == 0 &&
2264        UniStrCmpi(n1->Country, n2->Country) == 0 &&
2265        UniStrCmpi(n1->State, n2->State) == 0 &&
2266        UniStrCmpi(n1->Local, n2->Local) == 0)
2267    {
2268        return true;
2269    }
2270
2271    return false;
2272}
2273
2274// X の名前の解放
2275void FreeXNames(X *x)
2276{
2277    // 引数チェック
2278    if (x == NULL)
2279    {
2280        return;
2281    }
2282
2283    FreeName(x->issuer_name);
2284    x->issuer_name = NULL;
2285
2286    FreeName(x->subject_name);
2287    x->subject_name = NULL;
2288}
2289
2290// 名前の解放
2291void FreeName(NAME *n)
2292{
2293    // 引数チェック
2294    if (n == NULL)
2295    {
2296        return;
2297    }
2298
2299    // 文字列を解放
2300    Free(n->CommonName);
2301    Free(n->Organization);
2302    Free(n->Unit);
2303    Free(n->Country);
2304    Free(n->State);
2305    Free(n->Local);
2306
2307    // オブジェクトを解放
2308    Free(n);
2309
2310    return;
2311}
2312
2313// 証明書の名前を取得する
2314void LoadXNames(X *x)
2315{
2316    X509 *x509;
2317    // 引数チェック
2318    if (x == NULL)
2319    {
2320        return;
2321    }
2322
2323    x509 = x->x509;
2324    x->issuer_name = X509NameToName(X509_get_issuer_name(x509));
2325    x->subject_name = X509NameToName(X509_get_subject_name(x509));
2326}
2327
2328// X509_NAME 構造体を NAME 構造体に変換
2329NAME *X509NameToName(void *xn)
2330{
2331    NAME *n;
2332    // 引数チェック
2333    if (xn == NULL)
2334    {
2335        return NULL;
2336    }
2337
2338    n = ZeroMalloc(sizeof(NAME));
2339
2340    // 文字列を順番に取得する
2341    n->CommonName = GetUniStrFromX509Name(xn, NID_commonName);
2342    n->Organization = GetUniStrFromX509Name(xn, NID_organizationName);
2343    n->Unit = GetUniStrFromX509Name(xn, NID_organizationalUnitName);
2344    n->Country = GetUniStrFromX509Name(xn, NID_countryName);
2345    n->State = GetUniStrFromX509Name(xn, NID_stateOrProvinceName);
2346    n->Local = GetUniStrFromX509Name(xn, NID_localityName);
2347
2348    return n;
2349}
2350
2351// X509_NAME 構造体の中から Unicode 文字列を読み込む
2352wchar_t *GetUniStrFromX509Name(void *xn, int nid)
2353{
2354    UCHAR txt[1024];
2355    bool b = false;
2356    UINT i, size;
2357    int index;
2358    bool unicode = false;
2359    bool is_utf_8 = false;
2360    ASN1_OBJECT *obj;
2361    ASN1_STRING *data;
2362    // 引数チェック
2363    if (xn == NULL || nid == 0)
2364    {
2365        return NULL;
2366    }
2367
2368    Zero(txt, sizeof(txt));
2369    if (X509_NAME_get_text_by_NID(xn, nid, (char *)txt, sizeof(txt) - 2) <= 0)
2370    {
2371        return NULL;
2372    }
2373
2374    obj = OBJ_nid2obj(nid);
2375    if (obj == NULL)
2376    {
2377        return NULL;
2378    }
2379    index = X509_NAME_get_index_by_OBJ(xn, obj, -1);
2380    if (index < 0)
2381    {
2382        return NULL;
2383    }
2384    data = X509_NAME_ENTRY_get_data(X509_NAME_get_entry(xn, index));
2385    if (data == NULL)
2386    {
2387        return NULL;
2388    }
2389    if (data->type == V_ASN1_BMPSTRING)
2390    {
2391        unicode = true;
2392    }
2393    if (data->type == V_ASN1_UTF8STRING || data->type == V_ASN1_T61STRING)
2394    {
2395        is_utf_8 = true;
2396    }
2397
2398    size = UniStrLen((wchar_t *)txt) * 4 + 8;
2399    for (i = 0;i < size;i++)
2400    {
2401        if (txt[i] >= 0x80)
2402        {
2403            unicode = true;
2404            break;
2405        }
2406    }
2407
2408    if (is_utf_8)
2409    {
2410        wchar_t *ret;
2411        UINT ret_size;
2412
2413        ret_size = CalcUtf8ToUni(txt, StrLen(txt));
2414        ret = ZeroMalloc(ret_size + 8);
2415        Utf8ToUni(ret, ret_size, txt, StrLen(txt));
2416
2417        return ret;
2418    }
2419    else if (unicode == false)
2420    {
2421        wchar_t tmp[1024];
2422        StrToUni(tmp, sizeof(tmp), (char *)txt);
2423        return CopyUniStr(tmp);
2424    }
2425    else
2426    {
2427        EndianUnicode((wchar_t *)txt);
2428        return CopyUniStr((wchar_t *)txt);
2429    }
2430}
2431
2432// 証明書 x1 と x2 が等しいかどうかチェックする
2433bool CompareX(X *x1, X *x2)
2434{
2435    // 引数チェック
2436    if (x1 == NULL || x2 == NULL)
2437    {
2438        return false;
2439    }
2440
2441    Lock(openssl_lock);
2442    if (X509_cmp(x1->x509, x2->x509) == 0)
2443    {
2444        Unlock(openssl_lock);
2445        return true;
2446    }
2447    else
2448    {
2449        Unlock(openssl_lock);
2450        return false;
2451    }
2452}
2453
2454// K が X の秘密鍵かどうかチェックする
2455bool CheckXandK(X *x, K *k)
2456{
2457    // 引数チェック
2458    if (x == NULL || k == NULL)
2459    {
2460        return false;
2461    }
2462
2463    Lock(openssl_lock);
2464    if (X509_check_private_key(x->x509, k->pkey) != 0)
2465    {
2466        Unlock(openssl_lock);
2467        return true;
2468    }
2469    else
2470    {
2471        Unlock(openssl_lock);
2472        return false;
2473    }
2474}
2475
2476// ファイルから X を読み込む
2477X *FileToX(char *filename)
2478{
2479    wchar_t *filename_w = CopyStrToUni(filename);
2480    X *ret = FileToXW(filename_w);
2481
2482    Free(filename_w);
2483
2484    return ret;
2485}
2486X *FileToXW(wchar_t *filename)
2487{
2488    bool text;
2489    BUF *b;
2490    X *x;
2491    // 引数チェック
2492    if (filename == NULL)
2493    {
2494        return NULL;
2495    }
2496
2497    b = ReadDumpW(filename);
2498    text = IsBase64(b);
2499
2500    x = BufToX(b, text);
2501    FreeBuf(b);
2502
2503    return x;
2504}
2505
2506// X をファイルに書き出す
2507bool XToFile(X *x, char *filename, bool text)
2508{
2509    wchar_t *filename_w = CopyStrToUni(filename);
2510    bool ret = XToFileW(x, filename_w, text);
2511
2512    Free(filename_w);
2513
2514    return ret;
2515}
2516bool XToFileW(X *x, wchar_t *filename, bool text)
2517{
2518    BUF *b;
2519    bool ret;
2520    // 引数チェック
2521    if (x == NULL || filename == NULL)
2522    {
2523        return false;
2524    }
2525
2526    b = XToBuf(x, text);
2527    if (b == NULL)
2528    {
2529        return false;
2530    }
2531
2532    ret = DumpBufW(b, filename);
2533    FreeBuf(b);
2534
2535    return ret;
2536}
2537
2538// ファイルから K を読み込む
2539K *FileToK(char *filename, bool private_key, char *password)
2540{
2541    wchar_t *filename_w = CopyStrToUni(filename);
2542    K *ret;
2543
2544    ret = FileToKW(filename_w, private_key, password);
2545
2546    Free(filename_w);
2547
2548    return ret;
2549}
2550K *FileToKW(wchar_t *filename, bool private_key, char *password)
2551{
2552    bool text;
2553    BUF *b;
2554    K *k;
2555    // 引数チェック
2556    if (filename == NULL)
2557    {
2558        return NULL;
2559    }
2560
2561    b = ReadDumpW(filename);
2562    if (b == NULL)
2563    {
2564        return NULL;
2565    }
2566
2567    text = IsBase64(b);
2568    if (text == false)
2569    {
2570        k = BufToK(b, private_key, false, NULL);
2571    }
2572    else
2573    {
2574        k = BufToK(b, private_key, true, NULL);
2575        if (k == NULL)
2576        {
2577            k = BufToK(b, private_key, true, password);
2578        }
2579    }
2580
2581    FreeBuf(b);
2582
2583    return k;
2584}
2585
2586// K をファイルに保存する
2587bool KToFile(K *k, char *filename, bool text, char *password)
2588{
2589    wchar_t *filename_w = CopyStrToUni(filename);
2590    bool ret = KToFileW(k, filename_w, text, password);
2591
2592    Free(filename_w);
2593
2594    return ret;
2595}
2596bool KToFileW(K *k, wchar_t *filename, bool text, char *password)
2597{
2598    BUF *b;
2599    bool ret;
2600    // 引数チェック
2601    if (k == NULL || filename == NULL)
2602    {
2603        return false;
2604    }
2605
2606    b = KToBuf(k, text, password);
2607    if (b == NULL)
2608    {
2609        return false;
2610    }
2611
2612    ret = DumpBufW(b, filename);
2613    FreeBuf(b);
2614
2615    return ret;
2616}
2617
2618// K を BUF に変換する
2619BUF *KToBuf(K *k, bool text, char *password)
2620{
2621    BUF *buf;
2622    BIO *bio;
2623    // 引数チェック
2624    if (k == NULL)
2625    {
2626        return NULL;
2627    }
2628
2629    bio = KToBio(k, text, password);
2630    if (bio == NULL)
2631    {
2632        return NULL;
2633    }
2634
2635    buf = BioToBuf(bio);
2636    FreeBio(bio);
2637
2638    SeekBuf(buf, 0, 0);
2639
2640    return buf;
2641}
2642
2643// K を BIO に変換する
2644BIO *KToBio(K *k, bool text, char *password)
2645{
2646    BIO *bio;
2647    // 引数チェック
2648    if (k == NULL)
2649    {
2650        return NULL;
2651    }
2652
2653    bio = NewBio();
2654
2655    if (k->private_key)
2656    {
2657        // 秘密鍵
2658        if (text == false)
2659        {
2660            // バイナリ形式
2661            Lock(openssl_lock);
2662            {
2663                i2d_PrivateKey_bio(bio, k->pkey);
2664            }
2665            Unlock(openssl_lock);
2666        }
2667        else
2668        {
2669            // テキスト形式
2670            if (password == 0 || StrLen(password) == 0)
2671            {
2672                // 暗号化無し
2673                Lock(openssl_lock);
2674                {
2675                    PEM_write_bio_PrivateKey(bio, k->pkey, NULL, NULL, 0, NULL, NULL);
2676                }
2677                Unlock(openssl_lock);
2678            }
2679            else
2680            {
2681                // 暗号化する
2682                CB_PARAM cb;
2683                cb.password = password;
2684                Lock(openssl_lock);
2685                {
2686                    PEM_write_bio_PrivateKey(bio, k->pkey, EVP_des_ede3_cbc(),
2687                        NULL, 0, (pem_password_cb *)PKeyPasswordCallbackFunction, &cb);
2688                }
2689                Unlock(openssl_lock);
2690            }
2691        }
2692    }
2693    else
2694    {
2695        // 公開鍵
2696        if (text == false)
2697        {
2698            // バイナリ形式
2699            Lock(openssl_lock);
2700            {
2701                i2d_PUBKEY_bio(bio, k->pkey);
2702            }
2703            Unlock(openssl_lock);
2704        }
2705        else
2706        {
2707            // テキスト形式
2708            Lock(openssl_lock);
2709            {
2710                PEM_write_bio_PUBKEY(bio, k->pkey);
2711            }
2712            Unlock(openssl_lock);
2713        }
2714    }
2715
2716    return bio;
2717}
2718
2719// BUF が Base64 エンコードされているかどうか調べる
2720bool IsBase64(BUF *b)
2721{
2722    UINT i;
2723    // 引数チェック
2724    if (b == NULL)
2725    {
2726        return false;
2727    }
2728
2729    for (i = 0;i < b->Size;i++)
2730    {
2731        char c = ((char *)b->Buf)[i];
2732        bool b = false;
2733        if ('a' <= c && c <= 'z')
2734        {
2735            b = true;
2736        }
2737        else if ('A' <= c && c <= 'Z')
2738        {
2739            b = true;
2740        }
2741        else if ('0' <= c && c <= '9')
2742        {
2743            b = true;
2744        }
2745        else if (c == ':' || c == '.' || c == ';' || c == ',')
2746        {
2747            b = true;
2748        }
2749        else if (c == '!' || c == '&' || c == '#' || c == '(' || c == ')')
2750        {
2751            b = true;
2752        }
2753        else if (c == '-' || c == ' ')
2754        {
2755            b = true;
2756        }
2757        else if (c == 13 || c == 10 || c == EOF)
2758        {
2759            b = true;
2760        }
2761        else if (c == '\t' || c == '=' || c == '+' || c == '/')
2762        {
2763            b = true;
2764        }
2765        if (b == false)
2766        {
2767            return false;
2768        }
2769    }
2770    return true;
2771}
2772
2773// BUF に含まれている K が暗号化されているかどうか調べる
2774bool IsEncryptedK(BUF *b, bool private_key)
2775{
2776    K *k;
2777    // 引数チェック
2778    if (b == NULL)
2779    {
2780        return false;
2781    }
2782    if (IsBase64(b) == false)
2783    {
2784        return false;
2785    }
2786
2787    k = BufToK(b, private_key, true, NULL);
2788    if (k != NULL)
2789    {
2790        FreeK(k);
2791        return false;
2792    }
2793
2794    return true;
2795}
2796
2797// BUF を K に変換
2798K *BufToK(BUF *b, bool private_key, bool text, char *password)
2799{
2800    BIO *bio;
2801    K *k;
2802    // 引数チェック
2803    if (b == NULL)
2804    {
2805        return NULL;
2806    }
2807
2808    bio = BufToBio(b);
2809    k = BioToK(bio, private_key, text, password);
2810    FreeBio(bio);
2811
2812    return k;
2813}
2814
2815// K を解放
2816void FreeK(K *k)
2817{
2818    // 引数チェック
2819    if (k == NULL)
2820    {
2821        return;
2822    }
2823
2824    FreePKey(k->pkey);
2825    Free(k);
2826}
2827
2828// 秘密鍵を解放
2829void FreePKey(EVP_PKEY *pkey)
2830{
2831    // 引数チェック
2832    if (pkey == NULL)
2833    {
2834        return;
2835    }
2836
2837    EVP_PKEY_free(pkey);
2838}
2839
2840// BIO を K に変換する
2841K *BioToK(BIO *bio, bool private_key, bool text, char *password)
2842{
2843    EVP_PKEY *pkey;
2844    K *k;
2845    // 引数チェック
2846    if (bio == NULL)
2847    {
2848        return NULL;
2849    }
2850
2851    if (password != NULL && StrLen(password) == 0)
2852    {
2853        password = NULL;
2854    }
2855
2856    if (private_key == false)
2857    {
2858        // 公開鍵
2859        if (text == false)
2860        {
2861            // バイナリ形式
2862            pkey = d2i_PUBKEY_bio(bio, NULL);
2863            if (pkey == NULL)
2864            {
2865                return NULL;
2866            }
2867        }
2868        else
2869        {
2870            // テキスト形式
2871            CB_PARAM cb;
2872            cb.password = password;
2873            Lock(openssl_lock);
2874            {
2875                pkey = PEM_read_bio_PUBKEY(bio, NULL, (pem_password_cb *)PKeyPasswordCallbackFunction, &cb);
2876            }
2877            Unlock(openssl_lock);
2878            if (pkey == NULL)
2879            {
2880                return NULL;
2881            }
2882        }
2883    }
2884    else
2885    {
2886        if (text == false)
2887        {
2888            // バイナリ形式
2889            Lock(openssl_lock);
2890            {
2891                pkey = d2i_PrivateKey_bio(bio, NULL);
2892            }
2893            Unlock(openssl_lock);
2894            if (pkey == NULL)
2895            {
2896                return NULL;
2897            }
2898        }
2899        else
2900        {
2901            // テキスト形式
2902            CB_PARAM cb;
2903            cb.password = password;
2904            Lock(openssl_lock);
2905            {
2906                pkey = PEM_read_bio_PrivateKey(bio, NULL, (pem_password_cb *)PKeyPasswordCallbackFunction, &cb);
2907            }
2908            Unlock(openssl_lock);
2909            if (pkey == NULL)
2910            {
2911                return NULL;
2912            }
2913        }
2914    }
2915
2916    k = ZeroMalloc(sizeof(K));
2917    k->pkey = pkey;
2918    k->private_key = private_key;
2919
2920    return k;
2921}
2922
2923// パスワードコールバック関数
2924int PKeyPasswordCallbackFunction(char *buf, int bufsize, int verify, void *param)
2925{
2926    CB_PARAM *cb;
2927    // 引数チェック
2928    if (buf == NULL || param == NULL || bufsize == 0)
2929    {
2930        return 0;
2931    }
2932
2933    cb = (CB_PARAM *)param;
2934    if (cb->password == NULL)
2935    {
2936        return 0;
2937    }
2938
2939    return StrCpy(buf, bufsize, cb->password);
2940}
2941
2942// X を BUF に変換する
2943BUF *XToBuf(X *x, bool text)
2944{
2945    BIO *bio;
2946    BUF *b;
2947    // 引数チェック
2948    if (x == NULL)
2949    {
2950        return NULL;
2951    }
2952
2953    bio = XToBio(x, text);
2954    if (bio == NULL)
2955    {
2956        return NULL;
2957    }
2958
2959    b = BioToBuf(bio);
2960    FreeBio(bio);
2961
2962    SeekBuf(b, 0, 0);
2963
2964    return b;
2965}
2966
2967// X を BIO に変換する
2968BIO *XToBio(X *x, bool text)
2969{
2970    BIO *bio;
2971    // 引数チェック
2972    if (x == NULL)
2973    {
2974        return NULL;
2975    }
2976
2977    bio = NewBio();
2978
2979    Lock(openssl_lock);
2980    {
2981        if (text == false)
2982        {
2983            // バイナリ形式
2984            i2d_X509_bio(bio, x->x509);
2985        }
2986        else
2987        {
2988            // テキスト形式
2989            PEM_write_bio_X509(bio, x->x509);
2990        }
2991    }
2992    Unlock(openssl_lock);
2993
2994    return bio;
2995}
2996
2997// X の解放
2998void FreeX(X *x)
2999{
3000    // 引数チェック
3001    if (x == NULL)
3002    {
3003        return;
3004    }
3005
3006    // 名前解放
3007    FreeXNames(x);
3008
3009
3010    // シリアル解放
3011    FreeXSerial(x->serial);
3012
3013    if (x->do_not_free == false)
3014    {
3015        FreeX509(x->x509);
3016    }
3017    Free(x);
3018}
3019
3020// X509 の解放
3021void FreeX509(X509 *x509)
3022{
3023    // 引数チェック
3024    if (x509 == NULL)
3025    {
3026        return;
3027    }
3028
3029    Lock(openssl_lock);
3030    {
3031        X509_free(x509);
3032    }
3033    Unlock(openssl_lock);
3034}
3035
3036// BUF を X に変換する
3037X *BufToX(BUF *b, bool text)
3038{
3039    X *x;
3040    BIO *bio;
3041    // 引数チェック
3042    if (b == NULL)
3043    {
3044        return NULL;
3045    }
3046
3047    bio = BufToBio(b);
3048    if (bio == NULL)
3049    {
3050        return NULL;
3051    }
3052
3053    x = BioToX(bio, text);
3054
3055    FreeBio(bio);
3056
3057    return x;
3058}
3059
3060// X のダイジェストを取得する
3061void GetXDigest(X *x, UCHAR *buf, bool sha1)
3062{
3063    // 引数チェック
3064    if (x == NULL)
3065    {
3066        return;
3067    }
3068
3069    if (sha1 == false)
3070    {
3071        UINT size = MD5_SIZE;
3072        X509_digest(x->x509, EVP_md5(), buf, (unsigned int *)&size);
3073    }
3074    else
3075    {
3076        UINT size = SHA1_SIZE;
3077        X509_digest(x->x509, EVP_sha1(), buf, (unsigned int *)&size);
3078    }
3079}
3080
3081// BIO を X に変換する
3082X *BioToX(BIO *bio, bool text)
3083{
3084    X *x;
3085    X509 *x509;
3086    // 引数チェック
3087    if (bio == NULL)
3088    {
3089        return NULL;
3090    }
3091
3092    Lock(openssl_lock);
3093    {
3094        // x509 の読み込み
3095        if (text == false)
3096        {
3097            // バイナリモード
3098            x509 = d2i_X509_bio(bio, NULL);
3099        }
3100        else
3101        {
3102            // テキストモード
3103            x509 = PEM_read_bio_X509(bio, NULL, NULL, NULL);
3104        }
3105    }
3106    Unlock(openssl_lock);
3107
3108    if (x509 == NULL)
3109    {
3110        return NULL;
3111    }
3112
3113    x = X509ToX(x509);
3114
3115    if (x == NULL)
3116    {
3117        return NULL;
3118    }
3119
3120    return x;
3121}
3122
3123// X509 を X に変換する
3124X *X509ToX(X509 *x509)
3125{
3126    X *x;
3127    K *k;
3128    BUF *b;
3129    UINT size;
3130    UINT type;
3131    // 引数チェック
3132    if (x509 == NULL)
3133    {
3134        return NULL;
3135    }
3136
3137    x = ZeroMalloc(sizeof(X));
3138    x->x509 = x509;
3139
3140    // 名前
3141    LoadXNames(x);
3142
3143    // 有効期限
3144    LoadXDates(x);
3145
3146    // ルート証明書かどうかチェックする
3147    if (CompareName(x->issuer_name, x->subject_name))
3148    {
3149        K *pubkey = GetKFromX(x);
3150        if (pubkey != NULL)
3151        {
3152            if (CheckXandK(x, pubkey))
3153            {
3154                x->root_cert = true;
3155            }
3156            FreeK(pubkey);
3157        }
3158    }
3159
3160    // シリアル番号の取得
3161    x->serial = NewXSerial(x509->cert_info->serialNumber->data,
3162        x509->cert_info->serialNumber->length);
3163    if (x->serial == NULL)
3164    {
3165        char zero = 0;
3166        x->serial = NewXSerial(&zero, sizeof(char));
3167    }
3168
3169    k = GetKFromX(x);
3170    if (k == NULL)
3171    {
3172        FreeX(x);
3173        return NULL;
3174    }
3175
3176    b = KToBuf(k, false, NULL);
3177
3178    size = b->Size;
3179    type = k->pkey->type;
3180
3181    FreeBuf(b);
3182
3183    FreeK(k);
3184
3185    if (type == EVP_PKEY_RSA)
3186    {
3187        x->is_compatible_bit = true;
3188
3189        switch (size)
3190        {
3191        case 162:
3192            x->bits = 1024;
3193            break;
3194
3195        case 226:
3196            x->bits = 1536;
3197            break;
3198
3199        case 294:
3200            x->bits = 2048;
3201            break;
3202
3203        case 442:
3204            x->bits = 3072;
3205            break;
3206
3207        case 550:
3208            x->bits = 4096;
3209            break;
3210
3211        default:
3212            x->is_compatible_bit = false;
3213            break;
3214        }
3215    }
3216
3217    return x;
3218}
3219
3220// BIO を作成する
3221BIO *NewBio()
3222{
3223    return BIO_new(BIO_s_mem());
3224}
3225
3226// BIO を解放する
3227void FreeBio(BIO *bio)
3228{
3229    // 引数チェック
3230    if (bio == NULL)
3231    {
3232        return;
3233    }
3234
3235    BIO_free(bio);
3236}
3237
3238// BIO を BUF に変換する
3239BUF *BioToBuf(BIO *bio)
3240{
3241    BUF *b;
3242    UINT size;
3243    void *tmp;
3244    // 引数チェック
3245    if (bio == NULL)
3246    {
3247        return NULL;
3248    }
3249
3250    BIO_seek(bio, 0);
3251    size = bio->num_write;
3252    tmp = Malloc(size);
3253    BIO_read(bio, tmp, size);
3254
3255    b = NewBuf();
3256    WriteBuf(b, tmp, size);
3257    Free(tmp);
3258
3259    return b;
3260}
3261
3262// BUF を BIO に変換する
3263BIO *BufToBio(BUF *b)
3264{
3265    BIO *bio;
3266    // 引数チェック
3267    if (b == NULL)
3268    {
3269        return NULL;
3270    }
3271
3272    Lock(openssl_lock);
3273    {
3274        bio = BIO_new(BIO_s_mem());
3275        if (bio == NULL)
3276        {
3277            Unlock(openssl_lock);
3278            return NULL;
3279        }
3280        BIO_write(bio, b->Buf, b->Size);
3281        BIO_seek(bio, 0);
3282    }
3283    Unlock(openssl_lock);
3284
3285    return bio;
3286}
3287
3288// 128bit 乱数生成
3289void Rand128(void *buf)
3290{
3291    Rand(buf, 16);
3292}
3293
3294// 64bit 乱数生成
3295UINT64 Rand64()
3296{
3297    UINT64 i;
3298    Rand(&i, sizeof(i));
3299    return i;
3300}
3301
3302// 32bit 乱数生成
3303UINT Rand32()
3304{
3305    UINT i;
3306    Rand(&i, sizeof(i));
3307    return i;
3308}
3309
3310// 16bit 乱数生成
3311USHORT Rand16()
3312{
3313    USHORT i;
3314    Rand(&i, sizeof(i));
3315    return i;
3316}
3317
3318// 8bit 乱数生成
3319UCHAR Rand8()
3320{
3321    UCHAR i;
3322    Rand(&i, sizeof(i));
3323    return i;
3324}
3325
3326// 1bit 乱数生成
3327bool Rand1()
3328{
3329    return (Rand32() % 2) == 0 ? false : true;
3330}
3331
3332// 乱数生成
3333void Rand(void *buf, UINT size)
3334{
3335    // 引数チェック
3336    if (buf == NULL || size == 0)
3337    {
3338        return;
3339    }
3340    RAND_bytes(buf, size);
3341}
3342
3343// OpenSSL が確保しているスレッド固有情報を削除する
3344void FreeOpenSSLThreadState()
3345{
3346    ERR_remove_state(0);
3347}
3348
3349// 暗号化ライブラリの解放
3350void FreeCryptLibrary()
3351{
3352    openssl_inited = false;
3353
3354    DeleteLock(openssl_lock);
3355    openssl_lock = NULL;
3356//  RAND_Free_For_SoftEther();
3357    OpenSSL_FreeLock();
3358}
3359
3360// 暗号化ライブラリの初期化
3361void InitCryptLibrary()
3362{
3363    char tmp[16];
3364//  RAND_Init_For_SoftEther()
3365    openssl_lock = NewLock();
3366    SSL_library_init();
3367    //OpenSSL_add_all_algorithms();
3368    OpenSSL_add_all_ciphers();
3369    SSLeay_add_all_digests();
3370    ERR_load_crypto_strings();
3371    SSL_load_error_strings();
3372
3373#ifdef  OS_UNIX
3374    {
3375        char *name1 = "/dev/random";
3376        char *name2 = "/dev/urandom";
3377        IO *o;
3378        o = FileOpen(name1, false);
3379        if (o == NULL)
3380        {
3381            o = FileOpen(name2, false);
3382            if (o == NULL)
3383            {
3384                UINT64 now = SystemTime64();
3385                BUF *b;
3386                UINT i;
3387                b = NewBuf();
3388                for (i = 0;i < 4096;i++)
3389                {
3390                    UCHAR c = rand() % 256;
3391                    WriteBuf(b, &c, 1);
3392                }
3393                WriteBuf(b, &now, sizeof(now));
3394                RAND_seed(b->Buf, b->Size);
3395                FreeBuf(b);
3396            }
3397            else
3398            {
3399                FileClose(o);
3400            }
3401        }
3402        else
3403        {
3404            FileClose(o);
3405        }
3406    }
3407#endif  // OS_UNIX
3408
3409    RAND_poll();
3410
3411#ifdef  OS_WIN32
3412//  RAND_screen();
3413#endif
3414    Rand(tmp, sizeof(tmp));
3415    OpenSSL_InitLock();
3416
3417    openssl_inited = true;
3418}
3419
3420// 内部ハッシュ関数
3421void InternalHash(void *dst, void *src, UINT size, bool sha1)
3422{
3423    // 引数チェック
3424    if (dst == NULL || (src == NULL && size != 0))
3425    {
3426        return;
3427    }
3428
3429    if (sha1 == false)
3430    {
3431        // MD5 ハッシュ
3432        MD5(src, size, dst);
3433    }
3434    else
3435    {
3436        // SHA ハッシュ
3437        SHA(src, size, dst);
3438    }
3439}
3440
3441// SHA-1 専用ハッシュ関数
3442void HashSha1(void *dst, void *src, UINT size)
3443{
3444    SHA1(src, size, dst);
3445}
3446
3447// ハッシュ関数
3448void Hash(void *dst, void *src, UINT size, bool sha1)
3449{
3450    InternalHash(dst, src, size, sha1);
3451}
3452
3453// 新しい CRYPT オブジェクトの作成
3454CRYPT *NewCrypt(void *key, UINT size)
3455{
3456    CRYPT *c = ZeroMalloc(sizeof(CRYPT));
3457
3458    SetKey(c, key, size);
3459
3460    return c;
3461}
3462
3463// CRYPT オブジェクトの解放
3464void FreeCrypt(CRYPT *c)
3465{
3466    // 引数チェック
3467    if (c == NULL)
3468    {
3469        return;
3470    }
3471
3472    // メモリ解放
3473    Free(c);
3474}
3475
3476// 暗号化と解読
3477void InternalEncrypt(CRYPT *c, void *dst, void *src, UINT size)
3478{
3479    UINT x, y, sx, sy;
3480    UINT *state;
3481    UCHAR *endsrc;
3482    UCHAR *s = (UCHAR *)src;
3483    UCHAR *d = (UCHAR *)dst;
3484    // 引数チェック
3485    if (c == NULL || dst == NULL || src == NULL || size == 0)
3486    {
3487        return;
3488    }
3489
3490    state = (UINT *)c->state;
3491    x = c->x;
3492    y = c->y;
3493
3494    for (endsrc = s + size;s != endsrc;s++, d++)
3495    {
3496        x = (x + 1) & 0xff;
3497        sx = state[x];
3498        y = (sx + y) & 0xff;
3499        state[x] = sy = state[y];
3500        state[y] = sx;
3501        *d = *s ^ state[(sx + sy) & 0xff];
3502    }
3503    c->x = x;
3504    c->y = y;
3505}
3506void Encrypt(CRYPT *c, void *dst, void *src, UINT size)
3507{
3508    InternalEncrypt(c, dst, src, size);
3509}
3510
3511// 鍵の更新
3512void SetKey(CRYPT *c, void *key, UINT size)
3513{
3514    UINT i, t, u, ki, si;
3515    UINT *state;
3516    UCHAR *k = (UCHAR *)key;
3517    // 引数チェック
3518    if (c == NULL || key == NULL)
3519    {
3520        return;
3521    }
3522
3523    // 鍵のセット
3524    state = (UINT *)c->state;
3525    c->x = c->y = 0;
3526    for (i = 0;i < 256;i++)
3527    {
3528        state[i] = i;
3529    }
3530    ki = si = 0;
3531
3532    for (i = 0;i < 256;i++)
3533    {
3534        t = state[i];
3535        si = (si + k[ki] + t) & 0xff;
3536        u = state[si];
3537        state[si] = t;
3538        state[i] = u;
3539        if (++ki >= size)
3540        {
3541            ki = 0;
3542        }
3543    }
3544}
3545
Note: See TracBrowser for help on using the repository browser.