diff --git a/CMakeLists.txt b/CMakeLists.txt index d065316..905a550 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,5 +1,5 @@ cmake_minimum_required(VERSION 3.13) -project(dstu-engine LANGUAGES C VERSION 1.2.2) +project(dstu-engine LANGUAGES C VERSION 1.3.0) option(BUILD_TESTS "Build tests." OFF) option(ENABLE_CODECOV "Enable code coverage analysis." OFF) @@ -25,6 +25,7 @@ bugprone-*,\ -clang-analyzer-security.insecureAPI.DeprecatedOrUnsafeBufferHandling,\ -bugprone-easily-swappable-parameters,\ -modernize-avoid-bind,\ +-misc-no-recursion,\ -modernize-use-trailing-return-type,\ -readability-braces-around-statements, \ -readability-function-cognitive-complexity,\ diff --git a/Doxyfile b/Doxyfile index f73cda0..2d5933a 100644 --- a/Doxyfile +++ b/Doxyfile @@ -829,7 +829,7 @@ WARN_LOGFILE = # spaces. See also FILE_PATTERNS and EXTENSION_MAPPING # Note: If this tag is empty the current directory is searched. -INPUT = README.md keylib/key6.h keylib/jks.h +INPUT = README.md keylib/key6.h keylib/jks.h keylib/pkcs12.h keylib/keystore.h # This tag can be used to specify the character encoding of the source files # that doxygen parses. Internally doxygen uses the UTF-8 encoding. Doxygen uses diff --git a/README.md b/README.md index d3663af..b08241f 100644 --- a/README.md +++ b/README.md @@ -79,14 +79,10 @@ ENGINE_set_default(engine, ENGINE_METHOD_ALL); auto* fp = fopen(file.c_str(), "r"); -// Key-6.dat may contain 1 or 2 keys -EVP_PKEY** keys = nullptr; -size_t numKeys = 0; -readKey6(fp, password.c_str(), password.length(), &keys, &numKeys); - -// Delete all keys after use -for (size_t i = 0; i < numKeys; ++i) - EVP_PKEY_free(keys[i]); +KeyStore* ks = NULL; +readKey6(fp, password.c_str(), password.length(), &ks); + +KeyStoreFree(ks); OPENSSL_free(keys); fclose(fp); diff --git a/docs/dir_5e57c488afef9ef24045388a5764f023.html b/docs/dir_5e57c488afef9ef24045388a5764f023.html index 3c6a2f3..74990f4 100644 --- a/docs/dir_5e57c488afef9ef24045388a5764f023.html +++ b/docs/dir_5e57c488afef9ef24045388a5764f023.html @@ -1,9 +1,9 @@ - + - + Keylib: keylib Directory Reference @@ -30,21 +30,18 @@ - + +
file  key6.h [code]  Functions for reading keys from IIT Key-6.dat container.
  +file  keystore.h [code] + KeyStore is a container for keys and certificates.
+  +file  pkcs12.h [code] + Functions for reading keys from PKCS#12 container.
diff --git a/docs/doxygen.css b/docs/doxygen.css index 73ecbb2..4f1ab91 100644 --- a/docs/doxygen.css +++ b/docs/doxygen.css @@ -1,4 +1,4 @@ -/* The standard CSS for doxygen 1.8.17 */ +/* The standard CSS for doxygen 1.8.13 */ body, table, div, p, dl { font: 400 14px/22px Roboto,sans-serif; @@ -53,24 +53,17 @@ dt { font-weight: bold; } -ul.multicol { +div.multicol { -moz-column-gap: 1em; -webkit-column-gap: 1em; - column-gap: 1em; -moz-column-count: 3; -webkit-column-count: 3; - column-count: 3; } p.startli, p.startdd { margin-top: 2px; } -th p.starttd, p.intertd, p.endtd { - font-size: 100%; - font-weight: 700; -} - p.starttd { margin-top: 0px; } @@ -87,15 +80,6 @@ p.endtd { margin-bottom: 2px; } -p.interli { -} - -p.interdd { -} - -p.intertd { -} - /* @end */ caption { @@ -150,12 +134,12 @@ a.qindex { a.qindexHL { font-weight: bold; background-color: #9CAFD4; - color: #FFFFFF; + color: #ffffff; border: 1px double #869DCA; } .contents a.qindexHL:visited { - color: #FFFFFF; + color: #ffffff; } a.el { @@ -179,25 +163,6 @@ dl.el { margin-left: -1cm; } -ul { - overflow: hidden; /*Fixed: list item bullets overlap floating elements*/ -} - -#side-nav ul { - overflow: visible; /* reset ul rule for scroll bar in GENERATE_TREEVIEW window */ -} - -#main-nav ul { - overflow: visible; /* reset ul rule for the navigation bar drop down lists */ -} - -.fragment { - text-align: left; - direction: ltr; - overflow-x: auto; /*Fixed: fragment lines overlap floating elements*/ - overflow-y: hidden; -} - pre.fragment { border: 1px solid #C4CFE5; background-color: #FBFCFD; @@ -212,8 +177,8 @@ pre.fragment { } div.fragment { - padding: 0 0 1px 0; /*Fixed: last line underline overlap border*/ - margin: 4px 8px 4px 2px; + padding: 0px; + margin: 4px 8px 4px 2px; background-color: #FBFCFD; border: 1px solid #C4CFE5; } @@ -283,7 +248,7 @@ span.lineno a:hover { div.ah, span.ah { background-color: black; font-weight: bold; - color: #FFFFFF; + color: #ffffff; margin-bottom: 3px; margin-top: 3px; padding: 0.2em; @@ -359,7 +324,7 @@ img.formulaDsp { } -img.formulaInl, img.inline { +img.formulaInl { vertical-align: middle; } @@ -437,13 +402,6 @@ blockquote { padding: 0 12px 0 16px; } -blockquote.DocNodeRTL { - border-left: 0; - border-right: 2px solid #9CAFD4; - margin: 0 4px 0 24px; - padding: 0 16px 0 12px; -} - /* @end */ /* @@ -540,7 +498,7 @@ table.memberdecls { white-space: nowrap; } -.memItemRight, .memTemplItemRight { +.memItemRight { width: 100%; } @@ -708,17 +666,17 @@ dl.reflist dd { padding-left: 0px; } -.params .paramname, .retval .paramname, .tparams .paramname, .exception .paramname { +.params .paramname, .retval .paramname { font-weight: bold; vertical-align: top; } -.params .paramtype, .tparams .paramtype { +.params .paramtype { font-style: italic; vertical-align: top; } -.params .paramdir, .tparams .paramdir { +.params .paramdir { font-family: "courier new",courier,monospace; vertical-align: top; } @@ -1123,143 +1081,72 @@ div.headertitle padding: 5px 5px 5px 10px; } -.PageDocRTL-title div.headertitle { - text-align: right; - direction: rtl; -} - -dl { - padding: 0 0 0 0; +dl +{ + padding: 0 0 0 10px; } -/* dl.note, dl.warning, dl.attention, dl.pre, dl.post, dl.invariant, dl.deprecated, dl.todo, dl.test, dl.bug, dl.examples */ -dl.section { +/* dl.note, dl.warning, dl.attention, dl.pre, dl.post, dl.invariant, dl.deprecated, dl.todo, dl.test, dl.bug */ +dl.section +{ margin-left: 0px; padding-left: 0px; } -dl.section.DocNodeRTL { - margin-right: 0px; - padding-right: 0px; -} - -dl.note { - margin-left: -7px; - padding-left: 3px; - border-left: 4px solid; - border-color: #D0C000; -} - -dl.note.DocNodeRTL { - margin-left: 0; - padding-left: 0; - border-left: 0; - margin-right: -7px; - padding-right: 3px; - border-right: 4px solid; - border-color: #D0C000; -} - -dl.warning, dl.attention { - margin-left: -7px; - padding-left: 3px; - border-left: 4px solid; - border-color: #FF0000; -} - -dl.warning.DocNodeRTL, dl.attention.DocNodeRTL { - margin-left: 0; - padding-left: 0; - border-left: 0; - margin-right: -7px; - padding-right: 3px; - border-right: 4px solid; - border-color: #FF0000; -} - -dl.pre, dl.post, dl.invariant { - margin-left: -7px; - padding-left: 3px; - border-left: 4px solid; - border-color: #00D000; -} - -dl.pre.DocNodeRTL, dl.post.DocNodeRTL, dl.invariant.DocNodeRTL { - margin-left: 0; - padding-left: 0; - border-left: 0; - margin-right: -7px; - padding-right: 3px; - border-right: 4px solid; - border-color: #00D000; +dl.note +{ + margin-left:-7px; + padding-left: 3px; + border-left:4px solid; + border-color: #D0C000; } -dl.deprecated { - margin-left: -7px; - padding-left: 3px; - border-left: 4px solid; - border-color: #505050; +dl.warning, dl.attention +{ + margin-left:-7px; + padding-left: 3px; + border-left:4px solid; + border-color: #FF0000; } -dl.deprecated.DocNodeRTL { - margin-left: 0; - padding-left: 0; - border-left: 0; - margin-right: -7px; - padding-right: 3px; - border-right: 4px solid; - border-color: #505050; +dl.pre, dl.post, dl.invariant +{ + margin-left:-7px; + padding-left: 3px; + border-left:4px solid; + border-color: #00D000; } -dl.todo { - margin-left: -7px; - padding-left: 3px; - border-left: 4px solid; - border-color: #00C0E0; +dl.deprecated +{ + margin-left:-7px; + padding-left: 3px; + border-left:4px solid; + border-color: #505050; } -dl.todo.DocNodeRTL { - margin-left: 0; - padding-left: 0; - border-left: 0; - margin-right: -7px; - padding-right: 3px; - border-right: 4px solid; - border-color: #00C0E0; +dl.todo +{ + margin-left:-7px; + padding-left: 3px; + border-left:4px solid; + border-color: #00C0E0; } -dl.test { - margin-left: -7px; - padding-left: 3px; - border-left: 4px solid; - border-color: #3030E0; +dl.test +{ + margin-left:-7px; + padding-left: 3px; + border-left:4px solid; + border-color: #3030E0; } -dl.test.DocNodeRTL { - margin-left: 0; - padding-left: 0; - border-left: 0; - margin-right: -7px; - padding-right: 3px; - border-right: 4px solid; - border-color: #3030E0; -} - -dl.bug { - margin-left: -7px; - padding-left: 3px; - border-left: 4px solid; - border-color: #C08050; -} - -dl.bug.DocNodeRTL { - margin-left: 0; - padding-left: 0; - border-left: 0; - margin-right: -7px; - padding-right: 3px; - border-right: 4px solid; - border-color: #C08050; +dl.bug +{ + margin-left:-7px; + padding-left: 3px; + border-left:4px solid; + border-color: #C08050; } dl.section dd { @@ -1376,11 +1263,6 @@ div.toc { width: 200px; } -.PageDocRTL-title div.toc { - float: left !important; - text-align: right; -} - div.toc li { background: url("bdwn.png") no-repeat scroll 0 5px transparent; font: 10px/1.2 Verdana,DejaVu Sans,Geneva,sans-serif; @@ -1389,12 +1271,6 @@ div.toc li { padding-top: 2px; } -.PageDocRTL-title div.toc li { - background-position-x: right !important; - padding-left: 0 !important; - padding-right: 10px; -} - div.toc h3 { font: bold 12px/1.2 Arial,FreeSans,sans-serif; color: #4665A2; @@ -1424,26 +1300,6 @@ div.toc li.level4 { margin-left: 45px; } -.PageDocRTL-title div.toc li.level1 { - margin-left: 0 !important; - margin-right: 0; -} - -.PageDocRTL-title div.toc li.level2 { - margin-left: 0 !important; - margin-right: 15px; -} - -.PageDocRTL-title div.toc li.level3 { - margin-left: 0 !important; - margin-right: 30px; -} - -.PageDocRTL-title div.toc li.level4 { - margin-left: 0 !important; - margin-right: 45px; -} - .inherit_header { font-weight: bold; color: gray; @@ -1557,7 +1413,7 @@ tr.heading h2 { } #powerTip.n:after, #powerTip.ne:after, #powerTip.nw:after { - border-top-color: #FFFFFF; + border-top-color: #ffffff; border-width: 10px; margin: 0px -10px; } @@ -1585,7 +1441,7 @@ tr.heading h2 { } #powerTip.s:after, #powerTip.se:after, #powerTip.sw:after { - border-bottom-color: #FFFFFF; + border-bottom-color: #ffffff; border-width: 10px; margin: 0px -10px; } @@ -1612,7 +1468,7 @@ tr.heading h2 { left: 100%; } #powerTip.e:after { - border-left-color: #FFFFFF; + border-left-color: #ffffff; border-width: 10px; top: 50%; margin-top: -10px; @@ -1628,7 +1484,7 @@ tr.heading h2 { right: 100%; } #powerTip.w:after { - border-right-color: #FFFFFF; + border-right-color: #ffffff; border-width: 10px; top: 50%; margin-top: -10px; @@ -1736,36 +1592,5 @@ th.markdownTableHeadCenter, td.markdownTableBodyCenter { text-align: center } -.DocNodeRTL { - text-align: right; - direction: rtl; -} - -.DocNodeLTR { - text-align: left; - direction: ltr; -} - -table.DocNodeRTL { - width: auto; - margin-right: 0; - margin-left: auto; -} -table.DocNodeLTR { - width: auto; - margin-right: auto; - margin-left: 0; -} - -tt, code, kbd, samp -{ - display: inline-block; - direction:ltr; -} /* @end */ - -u { - text-decoration: underline; -} - diff --git a/docs/dynsections.js b/docs/dynsections.js index ea0a7b3..85e1836 100644 --- a/docs/dynsections.js +++ b/docs/dynsections.js @@ -1,26 +1,3 @@ -/* - @licstart The following is the entire license notice for the - JavaScript code in this file. - - Copyright (C) 1997-2017 by Dimitri van Heesch - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License along - with this program; if not, write to the Free Software Foundation, Inc., - 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - - @licend The above is the entire license notice - for the JavaScript code in this file - */ function toggleVisibility(linkObj) { var base = $(linkObj).attr('id'); @@ -38,7 +15,7 @@ function toggleVisibility(linkObj) summary.hide(); $(linkObj).removeClass('closed').addClass('opened'); $(trigger).attr('src',src.substring(0,src.length-10)+'open.png'); - } + } return false; } @@ -117,4 +94,4 @@ function toggleInherit(id) $(img).attr('src',src.substring(0,src.length-10)+'open.png'); } } -/* @license-end */ + diff --git a/docs/files.html b/docs/files.html index a47ed10..25f441b 100644 --- a/docs/files.html +++ b/docs/files.html @@ -1,9 +1,9 @@ - + - + Keylib: File List @@ -30,21 +30,18 @@ - + + @@ -71,6 +68,8 @@   keylib  jks.hFunctions for reading keys from Java Key Storage  key6.hFunctions for reading keys from IIT Key-6.dat container + keystore.hKeyStore is a container for keys and certificates + pkcs12.hFunctions for reading keys from PKCS#12 container @@ -78,7 +77,7 @@ diff --git a/docs/globals.html b/docs/globals.html index 9da8046..80d1ac1 100644 --- a/docs/globals.html +++ b/docs/globals.html @@ -1,9 +1,9 @@ - + - + Keylib: File Members @@ -30,21 +30,18 @@ - + + @@ -63,77 +60,50 @@
Here is a list of all documented file members with links to the documentation:
@@ -141,7 +111,7 @@ diff --git a/docs/globals_func.html b/docs/globals_func.html index 2f9a60b..e68b140 100644 --- a/docs/globals_func.html +++ b/docs/globals_func.html @@ -1,9 +1,9 @@ - + - + Keylib: File Members @@ -30,21 +30,18 @@ - + + @@ -63,59 +60,47 @@
 
@@ -123,7 +108,7 @@ diff --git a/docs/globals_type.html b/docs/globals_type.html index 8e67119..db7fe0c 100644 --- a/docs/globals_type.html +++ b/docs/globals_type.html @@ -1,9 +1,9 @@ - + - + Keylib: File Members @@ -30,21 +30,18 @@ - + + @@ -63,11 +60,8 @@
 
@@ -75,7 +69,7 @@ diff --git a/docs/index.html b/docs/index.html index 63c7da3..f3d2ea3 100644 --- a/docs/index.html +++ b/docs/index.html @@ -1,9 +1,9 @@ - + - + Keylib: Main Page @@ -30,21 +30,18 @@ - + + @@ -61,111 +58,26 @@ -
+
Keylib Documentation
-

Build and test codecov

+
+ +
+

DSTU OpenSSL engine and key reading library

A dynamically loadable OpenSSL engine that implements DSTU random bit generator, hash, symmetric cipher and digital signature algorithms.

This project is based on dstucrypt/openssl-dstu repository which is a fork of an outdated version of OpenSSL. I put their changes into an external engine and made them compatible with OpenSSL-1.1.0 and later. GOST-related parts are taken from gost-engine/engine repository.

keylib is a library for reading different key containers.

-

-Standards:

-
    -
  • DSTU GOST 34.311-95 - hash function.
  • -
  • DSTU GOST 28147:2009 - symmetric cipher, CFB mode.
  • -
  • DSTU 4145-2002 - elliptic curve digital signature algorithm (LE and BE keys) and random bit generator.
  • -
-

-Key containers:

-
    -
  • Key-6.dat - custom IIT key container with password protection.
  • -
-

-Building and installation instructions

-
mkdir build
-
cd build
-
cmake ..
-
make
-
sudo make install
-

-Build options:

-
    -
  • BUILD_TESTS - enable testing, default OFF.
  • -
  • ENABLE_CODECOV - enable code coverage analysis, default OFF.
  • -
-

-Requirements

-
    -
  • OpenSSL 1.1.0 or later.
  • -
-

-Documentation

-

Library reference

-

-Usage examples

-

-With <tt>openssl</tt> utility

-

Specify -engine dstu:

$ openssl cms -verify -engine dstu -in tests/cms.pem -inform PEM -noverify
-
engine "dstu" set.
-
Verification successful
-
<?xmlversion="1.0" encoding="windows-1251"?><RQ V="1"><DAT FN="4538765845" TN="345612052809" ZN="" DI="238" V="1"><C T="11"></C><TS>YYYYMMDDHHMMSS</TS></DAT><MAC></MAC></RQ>
-

-With API

-

Load 'dstu' engine with ENGINE_by_id and pass it to API functions:

{c++}
-
// Essential for engine loading
-
OPENSSL_init_crypto(OPENSSL_INIT_ENGINE_ALL_BUILTIN | OPENSSL_INIT_LOAD_CONFIG, nullptr);
-
-
// Get engine handle
-
auto* engine = ENGINE_by_id("dstu");
-
ENGINE_init(engine);
-
-
const auto* mdt = ENGINE_get_digest(engine, NID_dstu34311);
-
std::array<unsigned char, 32> res;
-
unsigned int s = 0;
-
EVP_Digest(data, size, res.data(), &s, mdt, engine);
-
// 'res' now contains the hash
-

-Keylib API

-
{c++}
-
// Essential for engine loading
-
OPENSSL_init_crypto(OPENSSL_INIT_ENGINE_ALL_BUILTIN | OPENSSL_INIT_LOAD_CONFIG, nullptr);
-
-
// Get engine handle
-
auto* engine = ENGINE_by_id("dstu");
-
ENGINE_init(engine);
-
-
ENGINE_set_default(engine, ENGINE_METHOD_ALL);
-
-
auto* fp = fopen(file.c_str(), "r");
-
-
// Key-6.dat may contain 1 or 2 keys
-
EVP_PKEY** keys = nullptr;
-
size_t numKeys = 0;
-
readKey6(fp, password.c_str(), password.length(), &keys, &numKeys);
-
-
// Delete all keys after use
-
for (size_t i = 0; i < numKeys; ++i)
-
EVP_PKEY_free(keys[i]);
-
OPENSSL_free(keys);
-
-
fclose(fp);
-

-Links

- -
-
+
diff --git a/docs/jks_8h.html b/docs/jks_8h.html index dd22bf1..49bf49a 100644 --- a/docs/jks_8h.html +++ b/docs/jks_8h.html @@ -1,9 +1,9 @@ - + - + Keylib: keylib/jks.h File Reference @@ -30,21 +30,18 @@ - + +
jks.h File Reference
@@ -77,260 +72,75 @@

Functions for reading keys from Java Key Storage. More...

-
#include <openssl/evp.h>
-#include <openssl/x509.h>
-#include <openssl/bio.h>
+
#include "keystore.h"
+#include <openssl/ossl_typ.h>
#include <stddef.h>
#include <stdio.h>

Go to the source code of this file.

- - - - - - - - - - - - - -

-Macros

-#define JKS_TYPE_JKS   0
 JKS in the original format.
 
-#define JKS_TYPE_JCEKS   1
 JKS in the improved fromat.
 
-#define JKS_ENTRY_PRIVATE_KEY   1
 private key JKS entry.
 
-#define JKS_ENTRY_CERT   2
 certificate JKS entry.
 
- - - - - - - -

-Typedefs

-typedef struct jks_st JKS
 JKS container handle.
 
-typedef struct jks_entry_st JKSEntry
 an element of a JKS container.
 
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + +

Functions

void JKSFree (JKS *jks)
 destroys JKS data. More...
 
size_t JKSType (const JKS *jks)
 returns JKS type. More...
 
size_t JKSEntryNum (const JKS *jks)
 returns a number of JKS entries. More...
 
JKSEntryJKSEntryGet (const JKS *jks, size_t pos)
 returns a pointer to the entry number 'pos'. The first entry is 0. More...
 
size_t JKSEntryType (const JKSEntry *entry)
 returns JKS entry type. More...
 
int JKSEntryDecrypt (JKSEntry *entry, const char *password, size_t passSize)
 decrypts an entry with private key material. Does nothig for other entry types. More...
 
const char * JKSEntryPKeyName (const JKSEntry *entry)
 returns an alias of a private key. Returns NULL for other entry types. More...
 
size_t JKSEntryPKeyNum (const JKSEntry *entry)
 returns a number of private keys in this entry. More...
 
const EVP_PKEY * JKSEntryPKey (const JKSEntry *entry, size_t pos)
 returns a pointer to an EVP_PKEY number 'pos'. More...
 
size_t JKSEntryCertNum (const JKSEntry *entry)
 returns a number of certificates in this entry. More...
 
const X509 * JKSEntryCert (const JKSEntry *entry, size_t pos)
 returns a pointer to a certificate number 'pos'. More...
 
const char * JKSEntryCertType (const JKSEntry *entry, size_t pos)
 returns a type of a certificate number 'pos'. More...
 
int parseJKS (const void *data, size_t size, const char *password, size_t passSize, JKS **keys)
 extracts private keys and certs from Java Key Store. More...
 
int readJKS (FILE *fp, const char *password, size_t passSize, JKS **keys)
 extracts private keys and certs from Java Key Store file. More...
 
int readJKS_bio (BIO *bio, const char *password, size_t passSize, JKS **keys)
 extracts private keys and certs from Java Key Store using OpenSSL BIO interface. More...
 
int parseJKS (const void *data, size_t size, const char *storagePass, size_t storagePassSize, const char *keyPass, size_t keyPassSize, KeyStore **ks)
 extracts private keys and certs from Java Key Store. More...
 
int readJKS (FILE *fp, const char *storagePass, size_t storagePassSize, const char *keyPass, size_t keyPassSize, KeyStore **ks)
 extracts private keys and certs from Java Key Store file. More...
 
int readJKS_bio (BIO *bio, const char *storagePass, size_t storagePassSize, const char *keyPass, size_t keyPassSize, KeyStore **ks)
 extracts private keys and certs from Java Key Store using OpenSSL BIO interface. More...
 

Detailed Description

Functions for reading keys from Java Key Storage.

Function Documentation

- -

◆ JKSEntryCert()

+ +

◆ parseJKS()

- + - - + + - - - - - - + -
const X509 * JKSEntryCert int parseJKS (const JKSEntryentry, const void * data,
size_t pos 
)size,
-
- -

returns a pointer to a certificate number 'pos'.

-
Parameters
- - - -
entrya pointer to the JKS entry;
poscertificate number, starting from 0.
-
-
-
Returns
the pointer to the certificate.
- -
-
- -

◆ JKSEntryCertNum()

- -
-
- - - - - + - -
size_t JKSEntryCertNum (const JKSEntryentry)
-
- -

returns a number of certificates in this entry.

-
Parameters
- - -
entrya pointer to the JKS entry.
-
-
-
Returns
the number of certificates.
- -
-
- -

◆ JKSEntryCertType()

- -
-
- - - - - - + + - - - - - - - -
const char * JKSEntryCertType (const JKSEntryentry, const char * storagePass,
size_t pos 
)
-
- -

returns a type of a certificate number 'pos'.

-
Parameters
- - - -
entrya pointer to the JKS entry;
poscertificate number, starting from 0.
-
-
-
Returns
the type of the certificate. Usually 'X509'.
- -
-
- -

◆ JKSEntryDecrypt()

- -
-
- - - - - - + - + - - - - - - - -
int JKSEntryDecrypt (JKSEntryentry, storagePassSize,
const char * password, keyPass,
size_t passSize 
)
-
- -

decrypts an entry with private key material. Does nothig for other entry types.

-
Parameters
- - - - -
entrya pointer to the JKS entry;
passwordprivate key encryption password;
passSizepassword size.
-
-
-
Returns
1 for success, 0 in case of failure.
- -
-
- -

◆ JKSEntryGet()

- -
-
- - - - - - + - - + + @@ -340,254 +150,64 @@

-

returns a pointer to the entry number 'pos'. The first entry is 0.

-
Parameters
-

JKSEntry JKSEntryGet (const JKSjks, keyPassSize,
size_t pos KeyStore ** ks 
- - -
jksJKS data;
posentry number starting from 0.
- - -
Returns
the pointer to the entry.
- -
-
- -

◆ JKSEntryNum()

- -
-
- - - - - - - - -
size_t JKSEntryNum (const JKSjks)
-
- -

returns a number of JKS entries.

+

extracts private keys and certs from Java Key Store.

Parameters
- + + + + + + +
jksJKS data.
datacontainer data;
sizecontainer data size;
storagePasscontainer password;
storagePassSizecontainer password size;
keyPasskey password;
keyPassSizekey password size;
ksKeyStore pointer outparam.
-
Returns
the number of entries in the store.
+
Returns
1 for success, 0 in case of failure.
- -

◆ JKSEntryPKey()

+ +

◆ readJKS()

- + - - + + - - - - - - - - -
const EVP_PKEY * JKSEntryPKey int readJKS (const JKSEntryentry, FILE * fp,
size_t pos 
)
-
- -

returns a pointer to an EVP_PKEY number 'pos'.

-
Parameters
- - - -
entrya pointer to the JKS entry;
posEVP_PKEY number, starting from 0.
-
-
-
Returns
the pointer to the EVP_PKEY.
-
Note
the entry must be decrypted first. Otherwise, the function returns NULL.
- -
-
- -

◆ JKSEntryPKeyName()

- -
-
- - - - - - - - -
const char * JKSEntryPKeyName (const JKSEntryentry)
-
- -

returns an alias of a private key. Returns NULL for other entry types.

-
Parameters
- - -
entrya pointer to the JKS entry.
-
-
-
Returns
the alias of the private key or NULL.
- -
-
- -

◆ JKSEntryPKeyNum()

- -
-
- - - - - - - - -
size_t JKSEntryPKeyNum (const JKSEntryentry)
-
- -

returns a number of private keys in this entry.

-
Parameters
- - -
entrya pointer to the JKS entry.
-
-
-
Returns
the number of private keys.
-
Note
the entry must be decrypted first. Otherwise, the function returns 0.
- -
-
- -

◆ JKSEntryType()

- -
-
- - - - - - - - -
size_t JKSEntryType (const JKSEntryentry)
-
- -

returns JKS entry type.

-
Parameters
- - -
entrya pointer to the JKS entry.
-
-
-
Returns
the type of the entry. JKS_ENTRY_PRIVATE_KEY - private key material, JKS_ENTRY_CERT - certificate.
- -
-
- -

◆ JKSFree()

- -
-
- - - - - - - - -
void JKSFree (JKSjks)
-
- -

destroys JKS data.

-
Parameters
- - -
jksJKS data;
-
-
- -
-
- -

◆ JKSType()

- -
-
- - - - - - - - -
size_t JKSType (const JKSjks)
-
- -

returns JKS type.

-
Parameters
- - -
jksJKS data.
-
-
-
Returns
the type of JKS. JKS_TYPE_JKS - original keystore format, JKS_TYPE_JCEKS - improved format.
- -
-
- -

◆ parseJKS()

- -
-
- - - - - - + + - + - + - + - - + + @@ -597,14 +217,15 @@

-

extracts private keys and certs from Java Key Store.

+

extracts private keys and certs from Java Key Store file.

Parameters

int parseJKS (const void * data, const char * storagePass,
size_t size, storagePassSize,
const char * password, keyPass,
size_t passSize, keyPassSize,
JKS ** keys KeyStore ** ks 
- - - - - + + + + + +
datacontainer data;
sizecontainer data size;
passwordcontainer password;
passSizepassword size;
keysJKS handle, extracted keys will be stored here.
fpfile handle;
storagePasscontainer password;
storagePassSizecontainer password size;
keyPasskey password;
keyPassSizekey password size;
ksKeyStore pointer outparam.
@@ -612,87 +233,47 @@

-

◆ readJKS()

+ +

◆ readJKS_bio()

- + - - + + - + - - - - - - - - - - - - - -
int readJKS int readJKS_bio (FILE * fp, BIO * bio,
const char * password, storagePass,
size_t passSize,
JKS ** keys 
)
-
- -

extracts private keys and certs from Java Key Store file.

-
Parameters
- - - - - -
fpfile handle;
passwordcontainer password;
passSizepassword size;
keysJKS handle, extracted keys will be stored here.
-
-
-
Returns
1 for success, 0 in case of failure.
- -
-
- -

◆ readJKS_bio()

- -
-
- - - - - - + - + - + - - + + @@ -706,9 +287,11 @@

Parameters

int readJKS_bio (BIO * bio, storagePassSize,
const char * password, keyPass,
size_t passSize, keyPassSize,
JKS ** keys KeyStore ** ks 
- - - + + + + +
bioOpenSSL BIO;
passwordcontainer password;
passSizepassword size;
keysJKS handle, extracted keys will be stored here.
storagePasscontainer password;
storagePassSizecontainer password size;
keyPasskey password;
keyPassSizekey password size;
ksKeyStore pointer outparam.
@@ -721,7 +304,7 @@

diff --git a/docs/jks_8h_source.html b/docs/jks_8h_source.html index b0ead56..8534913 100644 --- a/docs/jks_8h_source.html +++ b/docs/jks_8h_source.html @@ -1,9 +1,9 @@ - + - + Keylib: keylib/jks.h Source File @@ -30,21 +30,18 @@

- + +
jks.h
-Go to the documentation of this file.
1 #pragma once
-
2 
-
7 #include <openssl/evp.h>
-
8 #include <openssl/x509.h>
-
9 #include <openssl/bio.h>
-
10 
-
11 #include <stddef.h>
-
12 #include <stdio.h>
-
13 
-
14 #ifdef __cplusplus
-
15 extern "C" {
-
16 #endif
-
17 
-
21 typedef struct jks_st JKS;
-
25 typedef struct jks_entry_st JKSEntry;
-
26 
-
31 void JKSFree(JKS* jks);
-
32 
-
36 #define JKS_TYPE_JKS 0
-
37 
-
40 #define JKS_TYPE_JCEKS 1
-
41 
-
47 size_t JKSType(const JKS* jks);
-
48 
-
54 size_t JKSEntryNum(const JKS* jks);
-
61 JKSEntry* JKSEntryGet(const JKS* jks, size_t pos);
-
62 
-
66 #define JKS_ENTRY_PRIVATE_KEY 1
-
67 
-
70 #define JKS_ENTRY_CERT 2
-
71 
-
77 size_t JKSEntryType(const JKSEntry* entry);
-
78 
-
86 int JKSEntryDecrypt(JKSEntry* entry, const char* password, size_t passSize);
-
87 
-
93 const char* JKSEntryPKeyName(const JKSEntry* entry);
-
100 size_t JKSEntryPKeyNum(const JKSEntry* entry);
-
108 const EVP_PKEY* JKSEntryPKey(const JKSEntry* entry, size_t pos);
-
109 
-
115 size_t JKSEntryCertNum(const JKSEntry* entry);
-
122 const X509* JKSEntryCert(const JKSEntry* entry, size_t pos);
-
129 const char* JKSEntryCertType(const JKSEntry* entry, size_t pos);
-
130 
-
140 int parseJKS(const void* data, size_t size, const char* password, size_t passSize, JKS** keys);
-
141 
-
150 int readJKS(FILE* fp, const char* password, size_t passSize, JKS** keys);
-
151 
-
160 int readJKS_bio(BIO* bio, const char* password, size_t passSize, JKS** keys);
-
161 
-
162 #ifdef __cplusplus
-
163 }
-
164 #endif
+Go to the documentation of this file.
1 #pragma once
2 
7 #include "keystore.h"
8 
9 #include <openssl/ossl_typ.h>
10 
11 #include <stddef.h>
12 #include <stdio.h>
13 
14 #ifdef __cplusplus
15 extern "C" {
16 #endif
17 
29 int parseJKS(const void* data, size_t size, const char* storagePass, size_t storagePassSize, const char* keyPass, size_t keyPassSize, KeyStore** ks);
30 
41 int readJKS(FILE* fp, const char* storagePass, size_t storagePassSize, const char* keyPass, size_t keyPassSize, KeyStore** ks);
42 
53 int readJKS_bio(BIO* bio, const char* storagePass, size_t storagePassSize, const char* keyPass, size_t keyPassSize, KeyStore** ks);
54 
55 #ifdef __cplusplus
56 }
57 #endif
int parseJKS(const void *data, size_t size, const char *storagePass, size_t storagePassSize, const char *keyPass, size_t keyPassSize, KeyStore **ks)
extracts private keys and certs from Java Key Store.
+
int readJKS_bio(BIO *bio, const char *storagePass, size_t storagePassSize, const char *keyPass, size_t keyPassSize, KeyStore **ks)
extracts private keys and certs from Java Key Store using OpenSSL BIO interface.
+
int readJKS(FILE *fp, const char *storagePass, size_t storagePassSize, const char *keyPass, size_t keyPassSize, KeyStore **ks)
extracts private keys and certs from Java Key Store file.
+
struct KeyStore_st KeyStore
KeyStore container handle. It owns all keys and certificates inside.
Definition: keystore.h:18
+
KeyStore is a container for keys and certificates.
-
int readJKS(FILE *fp, const char *password, size_t passSize, JKS **keys)
extracts private keys and certs from Java Key Store file.
-
struct jks_st JKS
JKS container handle.
Definition: jks.h:21
-
int parseJKS(const void *data, size_t size, const char *password, size_t passSize, JKS **keys)
extracts private keys and certs from Java Key Store.
-
struct jks_entry_st JKSEntry
an element of a JKS container.
Definition: jks.h:25
-
const char * JKSEntryCertType(const JKSEntry *entry, size_t pos)
returns a type of a certificate number 'pos'.
-
const X509 * JKSEntryCert(const JKSEntry *entry, size_t pos)
returns a pointer to a certificate number 'pos'.
-
int JKSEntryDecrypt(JKSEntry *entry, const char *password, size_t passSize)
decrypts an entry with private key material. Does nothig for other entry types.
-
JKSEntry * JKSEntryGet(const JKS *jks, size_t pos)
returns a pointer to the entry number 'pos'. The first entry is 0.
-
size_t JKSEntryNum(const JKS *jks)
returns a number of JKS entries.
-
size_t JKSEntryCertNum(const JKSEntry *entry)
returns a number of certificates in this entry.
-
size_t JKSEntryPKeyNum(const JKSEntry *entry)
returns a number of private keys in this entry.
-
size_t JKSType(const JKS *jks)
returns JKS type.
-
const EVP_PKEY * JKSEntryPKey(const JKSEntry *entry, size_t pos)
returns a pointer to an EVP_PKEY number 'pos'.
-
size_t JKSEntryType(const JKSEntry *entry)
returns JKS entry type.
-
int readJKS_bio(BIO *bio, const char *password, size_t passSize, JKS **keys)
extracts private keys and certs from Java Key Store using OpenSSL BIO interface.
-
const char * JKSEntryPKeyName(const JKSEntry *entry)
returns an alias of a private key. Returns NULL for other entry types.
-
void JKSFree(JKS *jks)
destroys JKS data.
diff --git a/docs/jquery.js b/docs/jquery.js index 103c32d..f5343ed 100644 --- a/docs/jquery.js +++ b/docs/jquery.js @@ -1,26 +1,71 @@ -/*! jQuery v3.4.1 | (c) JS Foundation and other contributors | jquery.org/license */ -!function(e,t){"use strict";"object"==typeof module&&"object"==typeof module.exports?module.exports=e.document?t(e,!0):function(e){if(!e.document)throw new Error("jQuery requires a window with a document");return t(e)}:t(e)}("undefined"!=typeof window?window:this,function(C,e){"use strict";var t=[],E=C.document,r=Object.getPrototypeOf,s=t.slice,g=t.concat,u=t.push,i=t.indexOf,n={},o=n.toString,v=n.hasOwnProperty,a=v.toString,l=a.call(Object),y={},m=function(e){return"function"==typeof e&&"number"!=typeof e.nodeType},x=function(e){return null!=e&&e===e.window},c={type:!0,src:!0,nonce:!0,noModule:!0};function b(e,t,n){var r,i,o=(n=n||E).createElement("script");if(o.text=e,t)for(r in c)(i=t[r]||t.getAttribute&&t.getAttribute(r))&&o.setAttribute(r,i);n.head.appendChild(o).parentNode.removeChild(o)}function w(e){return null==e?e+"":"object"==typeof e||"function"==typeof e?n[o.call(e)]||"object":typeof e}var f="3.4.1",k=function(e,t){return new k.fn.init(e,t)},p=/^[\s\uFEFF\xA0]+|[\s\uFEFF\xA0]+$/g;function d(e){var t=!!e&&"length"in e&&e.length,n=w(e);return!m(e)&&!x(e)&&("array"===n||0===t||"number"==typeof t&&0+~]|"+M+")"+M+"*"),U=new RegExp(M+"|>"),X=new RegExp($),V=new RegExp("^"+I+"$"),G={ID:new RegExp("^#("+I+")"),CLASS:new RegExp("^\\.("+I+")"),TAG:new RegExp("^("+I+"|[*])"),ATTR:new RegExp("^"+W),PSEUDO:new RegExp("^"+$),CHILD:new RegExp("^:(only|first|last|nth|nth-last)-(child|of-type)(?:\\("+M+"*(even|odd|(([+-]|)(\\d*)n|)"+M+"*(?:([+-]|)"+M+"*(\\d+)|))"+M+"*\\)|)","i"),bool:new RegExp("^(?:"+R+")$","i"),needsContext:new RegExp("^"+M+"*[>+~]|:(even|odd|eq|gt|lt|nth|first|last)(?:\\("+M+"*((?:-\\d)?\\d*)"+M+"*\\)|)(?=[^-]|$)","i")},Y=/HTML$/i,Q=/^(?:input|select|textarea|button)$/i,J=/^h\d$/i,K=/^[^{]+\{\s*\[native \w/,Z=/^(?:#([\w-]+)|(\w+)|\.([\w-]+))$/,ee=/[+~]/,te=new RegExp("\\\\([\\da-f]{1,6}"+M+"?|("+M+")|.)","ig"),ne=function(e,t,n){var r="0x"+t-65536;return r!=r||n?t:r<0?String.fromCharCode(r+65536):String.fromCharCode(r>>10|55296,1023&r|56320)},re=/([\0-\x1f\x7f]|^-?\d)|^-$|[^\0-\x1f\x7f-\uFFFF\w-]/g,ie=function(e,t){return t?"\0"===e?"\ufffd":e.slice(0,-1)+"\\"+e.charCodeAt(e.length-1).toString(16)+" ":"\\"+e},oe=function(){T()},ae=be(function(e){return!0===e.disabled&&"fieldset"===e.nodeName.toLowerCase()},{dir:"parentNode",next:"legend"});try{H.apply(t=O.call(m.childNodes),m.childNodes),t[m.childNodes.length].nodeType}catch(e){H={apply:t.length?function(e,t){L.apply(e,O.call(t))}:function(e,t){var n=e.length,r=0;while(e[n++]=t[r++]);e.length=n-1}}}function se(t,e,n,r){var i,o,a,s,u,l,c,f=e&&e.ownerDocument,p=e?e.nodeType:9;if(n=n||[],"string"!=typeof t||!t||1!==p&&9!==p&&11!==p)return n;if(!r&&((e?e.ownerDocument||e:m)!==C&&T(e),e=e||C,E)){if(11!==p&&(u=Z.exec(t)))if(i=u[1]){if(9===p){if(!(a=e.getElementById(i)))return n;if(a.id===i)return n.push(a),n}else if(f&&(a=f.getElementById(i))&&y(e,a)&&a.id===i)return n.push(a),n}else{if(u[2])return H.apply(n,e.getElementsByTagName(t)),n;if((i=u[3])&&d.getElementsByClassName&&e.getElementsByClassName)return H.apply(n,e.getElementsByClassName(i)),n}if(d.qsa&&!A[t+" "]&&(!v||!v.test(t))&&(1!==p||"object"!==e.nodeName.toLowerCase())){if(c=t,f=e,1===p&&U.test(t)){(s=e.getAttribute("id"))?s=s.replace(re,ie):e.setAttribute("id",s=k),o=(l=h(t)).length;while(o--)l[o]="#"+s+" "+xe(l[o]);c=l.join(","),f=ee.test(t)&&ye(e.parentNode)||e}try{return H.apply(n,f.querySelectorAll(c)),n}catch(e){A(t,!0)}finally{s===k&&e.removeAttribute("id")}}}return g(t.replace(B,"$1"),e,n,r)}function ue(){var r=[];return function e(t,n){return r.push(t+" ")>b.cacheLength&&delete e[r.shift()],e[t+" "]=n}}function le(e){return e[k]=!0,e}function ce(e){var t=C.createElement("fieldset");try{return!!e(t)}catch(e){return!1}finally{t.parentNode&&t.parentNode.removeChild(t),t=null}}function fe(e,t){var n=e.split("|"),r=n.length;while(r--)b.attrHandle[n[r]]=t}function pe(e,t){var n=t&&e,r=n&&1===e.nodeType&&1===t.nodeType&&e.sourceIndex-t.sourceIndex;if(r)return r;if(n)while(n=n.nextSibling)if(n===t)return-1;return e?1:-1}function de(t){return function(e){return"input"===e.nodeName.toLowerCase()&&e.type===t}}function he(n){return function(e){var t=e.nodeName.toLowerCase();return("input"===t||"button"===t)&&e.type===n}}function ge(t){return function(e){return"form"in e?e.parentNode&&!1===e.disabled?"label"in e?"label"in e.parentNode?e.parentNode.disabled===t:e.disabled===t:e.isDisabled===t||e.isDisabled!==!t&&ae(e)===t:e.disabled===t:"label"in e&&e.disabled===t}}function ve(a){return le(function(o){return o=+o,le(function(e,t){var n,r=a([],e.length,o),i=r.length;while(i--)e[n=r[i]]&&(e[n]=!(t[n]=e[n]))})})}function ye(e){return e&&"undefined"!=typeof e.getElementsByTagName&&e}for(e in d=se.support={},i=se.isXML=function(e){var t=e.namespaceURI,n=(e.ownerDocument||e).documentElement;return!Y.test(t||n&&n.nodeName||"HTML")},T=se.setDocument=function(e){var t,n,r=e?e.ownerDocument||e:m;return r!==C&&9===r.nodeType&&r.documentElement&&(a=(C=r).documentElement,E=!i(C),m!==C&&(n=C.defaultView)&&n.top!==n&&(n.addEventListener?n.addEventListener("unload",oe,!1):n.attachEvent&&n.attachEvent("onunload",oe)),d.attributes=ce(function(e){return e.className="i",!e.getAttribute("className")}),d.getElementsByTagName=ce(function(e){return e.appendChild(C.createComment("")),!e.getElementsByTagName("*").length}),d.getElementsByClassName=K.test(C.getElementsByClassName),d.getById=ce(function(e){return a.appendChild(e).id=k,!C.getElementsByName||!C.getElementsByName(k).length}),d.getById?(b.filter.ID=function(e){var t=e.replace(te,ne);return function(e){return e.getAttribute("id")===t}},b.find.ID=function(e,t){if("undefined"!=typeof t.getElementById&&E){var n=t.getElementById(e);return n?[n]:[]}}):(b.filter.ID=function(e){var n=e.replace(te,ne);return function(e){var t="undefined"!=typeof e.getAttributeNode&&e.getAttributeNode("id");return t&&t.value===n}},b.find.ID=function(e,t){if("undefined"!=typeof t.getElementById&&E){var n,r,i,o=t.getElementById(e);if(o){if((n=o.getAttributeNode("id"))&&n.value===e)return[o];i=t.getElementsByName(e),r=0;while(o=i[r++])if((n=o.getAttributeNode("id"))&&n.value===e)return[o]}return[]}}),b.find.TAG=d.getElementsByTagName?function(e,t){return"undefined"!=typeof t.getElementsByTagName?t.getElementsByTagName(e):d.qsa?t.querySelectorAll(e):void 0}:function(e,t){var n,r=[],i=0,o=t.getElementsByTagName(e);if("*"===e){while(n=o[i++])1===n.nodeType&&r.push(n);return r}return o},b.find.CLASS=d.getElementsByClassName&&function(e,t){if("undefined"!=typeof t.getElementsByClassName&&E)return t.getElementsByClassName(e)},s=[],v=[],(d.qsa=K.test(C.querySelectorAll))&&(ce(function(e){a.appendChild(e).innerHTML="",e.querySelectorAll("[msallowcapture^='']").length&&v.push("[*^$]="+M+"*(?:''|\"\")"),e.querySelectorAll("[selected]").length||v.push("\\["+M+"*(?:value|"+R+")"),e.querySelectorAll("[id~="+k+"-]").length||v.push("~="),e.querySelectorAll(":checked").length||v.push(":checked"),e.querySelectorAll("a#"+k+"+*").length||v.push(".#.+[+~]")}),ce(function(e){e.innerHTML="";var t=C.createElement("input");t.setAttribute("type","hidden"),e.appendChild(t).setAttribute("name","D"),e.querySelectorAll("[name=d]").length&&v.push("name"+M+"*[*^$|!~]?="),2!==e.querySelectorAll(":enabled").length&&v.push(":enabled",":disabled"),a.appendChild(e).disabled=!0,2!==e.querySelectorAll(":disabled").length&&v.push(":enabled",":disabled"),e.querySelectorAll("*,:x"),v.push(",.*:")})),(d.matchesSelector=K.test(c=a.matches||a.webkitMatchesSelector||a.mozMatchesSelector||a.oMatchesSelector||a.msMatchesSelector))&&ce(function(e){d.disconnectedMatch=c.call(e,"*"),c.call(e,"[s!='']:x"),s.push("!=",$)}),v=v.length&&new RegExp(v.join("|")),s=s.length&&new RegExp(s.join("|")),t=K.test(a.compareDocumentPosition),y=t||K.test(a.contains)?function(e,t){var n=9===e.nodeType?e.documentElement:e,r=t&&t.parentNode;return e===r||!(!r||1!==r.nodeType||!(n.contains?n.contains(r):e.compareDocumentPosition&&16&e.compareDocumentPosition(r)))}:function(e,t){if(t)while(t=t.parentNode)if(t===e)return!0;return!1},D=t?function(e,t){if(e===t)return l=!0,0;var n=!e.compareDocumentPosition-!t.compareDocumentPosition;return n||(1&(n=(e.ownerDocument||e)===(t.ownerDocument||t)?e.compareDocumentPosition(t):1)||!d.sortDetached&&t.compareDocumentPosition(e)===n?e===C||e.ownerDocument===m&&y(m,e)?-1:t===C||t.ownerDocument===m&&y(m,t)?1:u?P(u,e)-P(u,t):0:4&n?-1:1)}:function(e,t){if(e===t)return l=!0,0;var n,r=0,i=e.parentNode,o=t.parentNode,a=[e],s=[t];if(!i||!o)return e===C?-1:t===C?1:i?-1:o?1:u?P(u,e)-P(u,t):0;if(i===o)return pe(e,t);n=e;while(n=n.parentNode)a.unshift(n);n=t;while(n=n.parentNode)s.unshift(n);while(a[r]===s[r])r++;return r?pe(a[r],s[r]):a[r]===m?-1:s[r]===m?1:0}),C},se.matches=function(e,t){return se(e,null,null,t)},se.matchesSelector=function(e,t){if((e.ownerDocument||e)!==C&&T(e),d.matchesSelector&&E&&!A[t+" "]&&(!s||!s.test(t))&&(!v||!v.test(t)))try{var n=c.call(e,t);if(n||d.disconnectedMatch||e.document&&11!==e.document.nodeType)return n}catch(e){A(t,!0)}return 0":{dir:"parentNode",first:!0}," ":{dir:"parentNode"},"+":{dir:"previousSibling",first:!0},"~":{dir:"previousSibling"}},preFilter:{ATTR:function(e){return e[1]=e[1].replace(te,ne),e[3]=(e[3]||e[4]||e[5]||"").replace(te,ne),"~="===e[2]&&(e[3]=" "+e[3]+" "),e.slice(0,4)},CHILD:function(e){return e[1]=e[1].toLowerCase(),"nth"===e[1].slice(0,3)?(e[3]||se.error(e[0]),e[4]=+(e[4]?e[5]+(e[6]||1):2*("even"===e[3]||"odd"===e[3])),e[5]=+(e[7]+e[8]||"odd"===e[3])):e[3]&&se.error(e[0]),e},PSEUDO:function(e){var t,n=!e[6]&&e[2];return G.CHILD.test(e[0])?null:(e[3]?e[2]=e[4]||e[5]||"":n&&X.test(n)&&(t=h(n,!0))&&(t=n.indexOf(")",n.length-t)-n.length)&&(e[0]=e[0].slice(0,t),e[2]=n.slice(0,t)),e.slice(0,3))}},filter:{TAG:function(e){var t=e.replace(te,ne).toLowerCase();return"*"===e?function(){return!0}:function(e){return e.nodeName&&e.nodeName.toLowerCase()===t}},CLASS:function(e){var t=p[e+" "];return t||(t=new RegExp("(^|"+M+")"+e+"("+M+"|$)"))&&p(e,function(e){return t.test("string"==typeof e.className&&e.className||"undefined"!=typeof e.getAttribute&&e.getAttribute("class")||"")})},ATTR:function(n,r,i){return function(e){var t=se.attr(e,n);return null==t?"!="===r:!r||(t+="","="===r?t===i:"!="===r?t!==i:"^="===r?i&&0===t.indexOf(i):"*="===r?i&&-1:\x20\t\r\n\f]*)[\x20\t\r\n\f]*\/?>(?:<\/\1>|)$/i;function j(e,n,r){return m(n)?k.grep(e,function(e,t){return!!n.call(e,t,e)!==r}):n.nodeType?k.grep(e,function(e){return e===n!==r}):"string"!=typeof n?k.grep(e,function(e){return-1)[^>]*|#([\w-]+))$/;(k.fn.init=function(e,t,n){var r,i;if(!e)return this;if(n=n||q,"string"==typeof e){if(!(r="<"===e[0]&&">"===e[e.length-1]&&3<=e.length?[null,e,null]:L.exec(e))||!r[1]&&t)return!t||t.jquery?(t||n).find(e):this.constructor(t).find(e);if(r[1]){if(t=t instanceof k?t[0]:t,k.merge(this,k.parseHTML(r[1],t&&t.nodeType?t.ownerDocument||t:E,!0)),D.test(r[1])&&k.isPlainObject(t))for(r in t)m(this[r])?this[r](t[r]):this.attr(r,t[r]);return this}return(i=E.getElementById(r[2]))&&(this[0]=i,this.length=1),this}return e.nodeType?(this[0]=e,this.length=1,this):m(e)?void 0!==n.ready?n.ready(e):e(k):k.makeArray(e,this)}).prototype=k.fn,q=k(E);var H=/^(?:parents|prev(?:Until|All))/,O={children:!0,contents:!0,next:!0,prev:!0};function P(e,t){while((e=e[t])&&1!==e.nodeType);return e}k.fn.extend({has:function(e){var t=k(e,this),n=t.length;return this.filter(function(){for(var e=0;e\x20\t\r\n\f]*)/i,he=/^$|^module$|\/(?:java|ecma)script/i,ge={option:[1,""],thead:[1,"","
"],col:[2,"","
"],tr:[2,"","
"],td:[3,"","
"],_default:[0,"",""]};function ve(e,t){var n;return n="undefined"!=typeof e.getElementsByTagName?e.getElementsByTagName(t||"*"):"undefined"!=typeof e.querySelectorAll?e.querySelectorAll(t||"*"):[],void 0===t||t&&A(e,t)?k.merge([e],n):n}function ye(e,t){for(var n=0,r=e.length;nx",y.noCloneChecked=!!me.cloneNode(!0).lastChild.defaultValue;var Te=/^key/,Ce=/^(?:mouse|pointer|contextmenu|drag|drop)|click/,Ee=/^([^.]*)(?:\.(.+)|)/;function ke(){return!0}function Se(){return!1}function Ne(e,t){return e===function(){try{return E.activeElement}catch(e){}}()==("focus"===t)}function Ae(e,t,n,r,i,o){var a,s;if("object"==typeof t){for(s in"string"!=typeof n&&(r=r||n,n=void 0),t)Ae(e,s,n,r,t[s],o);return e}if(null==r&&null==i?(i=n,r=n=void 0):null==i&&("string"==typeof n?(i=r,r=void 0):(i=r,r=n,n=void 0)),!1===i)i=Se;else if(!i)return e;return 1===o&&(a=i,(i=function(e){return k().off(e),a.apply(this,arguments)}).guid=a.guid||(a.guid=k.guid++)),e.each(function(){k.event.add(this,t,i,r,n)})}function De(e,i,o){o?(Q.set(e,i,!1),k.event.add(e,i,{namespace:!1,handler:function(e){var t,n,r=Q.get(this,i);if(1&e.isTrigger&&this[i]){if(r.length)(k.event.special[i]||{}).delegateType&&e.stopPropagation();else if(r=s.call(arguments),Q.set(this,i,r),t=o(this,i),this[i](),r!==(n=Q.get(this,i))||t?Q.set(this,i,!1):n={},r!==n)return e.stopImmediatePropagation(),e.preventDefault(),n.value}else r.length&&(Q.set(this,i,{value:k.event.trigger(k.extend(r[0],k.Event.prototype),r.slice(1),this)}),e.stopImmediatePropagation())}})):void 0===Q.get(e,i)&&k.event.add(e,i,ke)}k.event={global:{},add:function(t,e,n,r,i){var o,a,s,u,l,c,f,p,d,h,g,v=Q.get(t);if(v){n.handler&&(n=(o=n).handler,i=o.selector),i&&k.find.matchesSelector(ie,i),n.guid||(n.guid=k.guid++),(u=v.events)||(u=v.events={}),(a=v.handle)||(a=v.handle=function(e){return"undefined"!=typeof k&&k.event.triggered!==e.type?k.event.dispatch.apply(t,arguments):void 0}),l=(e=(e||"").match(R)||[""]).length;while(l--)d=g=(s=Ee.exec(e[l])||[])[1],h=(s[2]||"").split(".").sort(),d&&(f=k.event.special[d]||{},d=(i?f.delegateType:f.bindType)||d,f=k.event.special[d]||{},c=k.extend({type:d,origType:g,data:r,handler:n,guid:n.guid,selector:i,needsContext:i&&k.expr.match.needsContext.test(i),namespace:h.join(".")},o),(p=u[d])||((p=u[d]=[]).delegateCount=0,f.setup&&!1!==f.setup.call(t,r,h,a)||t.addEventListener&&t.addEventListener(d,a)),f.add&&(f.add.call(t,c),c.handler.guid||(c.handler.guid=n.guid)),i?p.splice(p.delegateCount++,0,c):p.push(c),k.event.global[d]=!0)}},remove:function(e,t,n,r,i){var o,a,s,u,l,c,f,p,d,h,g,v=Q.hasData(e)&&Q.get(e);if(v&&(u=v.events)){l=(t=(t||"").match(R)||[""]).length;while(l--)if(d=g=(s=Ee.exec(t[l])||[])[1],h=(s[2]||"").split(".").sort(),d){f=k.event.special[d]||{},p=u[d=(r?f.delegateType:f.bindType)||d]||[],s=s[2]&&new RegExp("(^|\\.)"+h.join("\\.(?:.*\\.|)")+"(\\.|$)"),a=o=p.length;while(o--)c=p[o],!i&&g!==c.origType||n&&n.guid!==c.guid||s&&!s.test(c.namespace)||r&&r!==c.selector&&("**"!==r||!c.selector)||(p.splice(o,1),c.selector&&p.delegateCount--,f.remove&&f.remove.call(e,c));a&&!p.length&&(f.teardown&&!1!==f.teardown.call(e,h,v.handle)||k.removeEvent(e,d,v.handle),delete u[d])}else for(d in u)k.event.remove(e,d+t[l],n,r,!0);k.isEmptyObject(u)&&Q.remove(e,"handle events")}},dispatch:function(e){var t,n,r,i,o,a,s=k.event.fix(e),u=new Array(arguments.length),l=(Q.get(this,"events")||{})[s.type]||[],c=k.event.special[s.type]||{};for(u[0]=s,t=1;t\x20\t\r\n\f]*)[^>]*)\/>/gi,qe=/\s*$/g;function Oe(e,t){return A(e,"table")&&A(11!==t.nodeType?t:t.firstChild,"tr")&&k(e).children("tbody")[0]||e}function Pe(e){return e.type=(null!==e.getAttribute("type"))+"/"+e.type,e}function Re(e){return"true/"===(e.type||"").slice(0,5)?e.type=e.type.slice(5):e.removeAttribute("type"),e}function Me(e,t){var n,r,i,o,a,s,u,l;if(1===t.nodeType){if(Q.hasData(e)&&(o=Q.access(e),a=Q.set(t,o),l=o.events))for(i in delete a.handle,a.events={},l)for(n=0,r=l[i].length;n")},clone:function(e,t,n){var r,i,o,a,s,u,l,c=e.cloneNode(!0),f=oe(e);if(!(y.noCloneChecked||1!==e.nodeType&&11!==e.nodeType||k.isXMLDoc(e)))for(a=ve(c),r=0,i=(o=ve(e)).length;r").attr(n.scriptAttrs||{}).prop({charset:n.scriptCharset,src:n.url}).on("load error",i=function(e){r.remove(),i=null,e&&t("error"===e.type?404:200,e.type)}),E.head.appendChild(r[0])},abort:function(){i&&i()}}});var Vt,Gt=[],Yt=/(=)\?(?=&|$)|\?\?/;k.ajaxSetup({jsonp:"callback",jsonpCallback:function(){var e=Gt.pop()||k.expando+"_"+kt++;return this[e]=!0,e}}),k.ajaxPrefilter("json jsonp",function(e,t,n){var r,i,o,a=!1!==e.jsonp&&(Yt.test(e.url)?"url":"string"==typeof e.data&&0===(e.contentType||"").indexOf("application/x-www-form-urlencoded")&&Yt.test(e.data)&&"data");if(a||"jsonp"===e.dataTypes[0])return r=e.jsonpCallback=m(e.jsonpCallback)?e.jsonpCallback():e.jsonpCallback,a?e[a]=e[a].replace(Yt,"$1"+r):!1!==e.jsonp&&(e.url+=(St.test(e.url)?"&":"?")+e.jsonp+"="+r),e.converters["script json"]=function(){return o||k.error(r+" was not called"),o[0]},e.dataTypes[0]="json",i=C[r],C[r]=function(){o=arguments},n.always(function(){void 0===i?k(C).removeProp(r):C[r]=i,e[r]&&(e.jsonpCallback=t.jsonpCallback,Gt.push(r)),o&&m(i)&&i(o[0]),o=i=void 0}),"script"}),y.createHTMLDocument=((Vt=E.implementation.createHTMLDocument("").body).innerHTML="
",2===Vt.childNodes.length),k.parseHTML=function(e,t,n){return"string"!=typeof e?[]:("boolean"==typeof t&&(n=t,t=!1),t||(y.createHTMLDocument?((r=(t=E.implementation.createHTMLDocument("")).createElement("base")).href=E.location.href,t.head.appendChild(r)):t=E),o=!n&&[],(i=D.exec(e))?[t.createElement(i[1])]:(i=we([e],t,o),o&&o.length&&k(o).remove(),k.merge([],i.childNodes)));var r,i,o},k.fn.load=function(e,t,n){var r,i,o,a=this,s=e.indexOf(" ");return-1").append(k.parseHTML(e)).find(r):e)}).always(n&&function(e,t){a.each(function(){n.apply(this,o||[e.responseText,t,e])})}),this},k.each(["ajaxStart","ajaxStop","ajaxComplete","ajaxError","ajaxSuccess","ajaxSend"],function(e,t){k.fn[t]=function(e){return this.on(t,e)}}),k.expr.pseudos.animated=function(t){return k.grep(k.timers,function(e){return t===e.elem}).length},k.offset={setOffset:function(e,t,n){var r,i,o,a,s,u,l=k.css(e,"position"),c=k(e),f={};"static"===l&&(e.style.position="relative"),s=c.offset(),o=k.css(e,"top"),u=k.css(e,"left"),("absolute"===l||"fixed"===l)&&-1<(o+u).indexOf("auto")?(a=(r=c.position()).top,i=r.left):(a=parseFloat(o)||0,i=parseFloat(u)||0),m(t)&&(t=t.call(e,n,k.extend({},s))),null!=t.top&&(f.top=t.top-s.top+a),null!=t.left&&(f.left=t.left-s.left+i),"using"in t?t.using.call(e,f):c.css(f)}},k.fn.extend({offset:function(t){if(arguments.length)return void 0===t?this:this.each(function(e){k.offset.setOffset(this,t,e)});var e,n,r=this[0];return r?r.getClientRects().length?(e=r.getBoundingClientRect(),n=r.ownerDocument.defaultView,{top:e.top+n.pageYOffset,left:e.left+n.pageXOffset}):{top:0,left:0}:void 0},position:function(){if(this[0]){var e,t,n,r=this[0],i={top:0,left:0};if("fixed"===k.css(r,"position"))t=r.getBoundingClientRect();else{t=this.offset(),n=r.ownerDocument,e=r.offsetParent||n.documentElement;while(e&&(e===n.body||e===n.documentElement)&&"static"===k.css(e,"position"))e=e.parentNode;e&&e!==r&&1===e.nodeType&&((i=k(e).offset()).top+=k.css(e,"borderTopWidth",!0),i.left+=k.css(e,"borderLeftWidth",!0))}return{top:t.top-i.top-k.css(r,"marginTop",!0),left:t.left-i.left-k.css(r,"marginLeft",!0)}}},offsetParent:function(){return this.map(function(){var e=this.offsetParent;while(e&&"static"===k.css(e,"position"))e=e.offsetParent;return e||ie})}}),k.each({scrollLeft:"pageXOffset",scrollTop:"pageYOffset"},function(t,i){var o="pageYOffset"===i;k.fn[t]=function(e){return _(this,function(e,t,n){var r;if(x(e)?r=e:9===e.nodeType&&(r=e.defaultView),void 0===n)return r?r[i]:e[t];r?r.scrollTo(o?r.pageXOffset:n,o?n:r.pageYOffset):e[t]=n},t,e,arguments.length)}}),k.each(["top","left"],function(e,n){k.cssHooks[n]=ze(y.pixelPosition,function(e,t){if(t)return t=_e(e,n),$e.test(t)?k(e).position()[n]+"px":t})}),k.each({Height:"height",Width:"width"},function(a,s){k.each({padding:"inner"+a,content:s,"":"outer"+a},function(r,o){k.fn[o]=function(e,t){var n=arguments.length&&(r||"boolean"!=typeof e),i=r||(!0===e||!0===t?"margin":"border");return _(this,function(e,t,n){var r;return x(e)?0===o.indexOf("outer")?e["inner"+a]:e.document.documentElement["client"+a]:9===e.nodeType?(r=e.documentElement,Math.max(e.body["scroll"+a],r["scroll"+a],e.body["offset"+a],r["offset"+a],r["client"+a])):void 0===n?k.css(e,t,i):k.style(e,t,n,i)},s,n?e:void 0,n)}})}),k.each("blur focus focusin focusout resize scroll click dblclick mousedown mouseup mousemove mouseover mouseout mouseenter mouseleave change select submit keydown keypress keyup contextmenu".split(" "),function(e,n){k.fn[n]=function(e,t){return 0a;a++)for(i in o[a])n=o[a][i],o[a].hasOwnProperty(i)&&void 0!==n&&(e[i]=t.isPlainObject(n)?t.isPlainObject(e[i])?t.widget.extend({},e[i],n):t.widget.extend({},n):n);return e},t.widget.bridge=function(e,i){var n=i.prototype.widgetFullName||e;t.fn[e]=function(o){var a="string"==typeof o,r=s.call(arguments,1),h=this;return a?this.length||"instance"!==o?this.each(function(){var i,s=t.data(this,n);return"instance"===o?(h=s,!1):s?t.isFunction(s[o])&&"_"!==o.charAt(0)?(i=s[o].apply(s,r),i!==s&&void 0!==i?(h=i&&i.jquery?h.pushStack(i.get()):i,!1):void 0):t.error("no such method '"+o+"' for "+e+" widget instance"):t.error("cannot call methods on "+e+" prior to initialization; "+"attempted to call method '"+o+"'")}):h=void 0:(r.length&&(o=t.widget.extend.apply(null,[o].concat(r))),this.each(function(){var e=t.data(this,n);e?(e.option(o||{}),e._init&&e._init()):t.data(this,n,new i(o,this))})),h}},t.Widget=function(){},t.Widget._childConstructors=[],t.Widget.prototype={widgetName:"widget",widgetEventPrefix:"",defaultElement:"
",options:{classes:{},disabled:!1,create:null},_createWidget:function(e,s){s=t(s||this.defaultElement||this)[0],this.element=t(s),this.uuid=i++,this.eventNamespace="."+this.widgetName+this.uuid,this.bindings=t(),this.hoverable=t(),this.focusable=t(),this.classesElementLookup={},s!==this&&(t.data(s,this.widgetFullName,this),this._on(!0,this.element,{remove:function(t){t.target===s&&this.destroy()}}),this.document=t(s.style?s.ownerDocument:s.document||s),this.window=t(this.document[0].defaultView||this.document[0].parentWindow)),this.options=t.widget.extend({},this.options,this._getCreateOptions(),e),this._create(),this.options.disabled&&this._setOptionDisabled(this.options.disabled),this._trigger("create",null,this._getCreateEventData()),this._init()},_getCreateOptions:function(){return{}},_getCreateEventData:t.noop,_create:t.noop,_init:t.noop,destroy:function(){var e=this;this._destroy(),t.each(this.classesElementLookup,function(t,i){e._removeClass(i,t)}),this.element.off(this.eventNamespace).removeData(this.widgetFullName),this.widget().off(this.eventNamespace).removeAttr("aria-disabled"),this.bindings.off(this.eventNamespace)},_destroy:t.noop,widget:function(){return this.element},option:function(e,i){var s,n,o,a=e;if(0===arguments.length)return t.widget.extend({},this.options);if("string"==typeof e)if(a={},s=e.split("."),e=s.shift(),s.length){for(n=a[e]=t.widget.extend({},this.options[e]),o=0;s.length-1>o;o++)n[s[o]]=n[s[o]]||{},n=n[s[o]];if(e=s.pop(),1===arguments.length)return void 0===n[e]?null:n[e];n[e]=i}else{if(1===arguments.length)return void 0===this.options[e]?null:this.options[e];a[e]=i}return this._setOptions(a),this},_setOptions:function(t){var e;for(e in t)this._setOption(e,t[e]);return this},_setOption:function(t,e){return"classes"===t&&this._setOptionClasses(e),this.options[t]=e,"disabled"===t&&this._setOptionDisabled(e),this},_setOptionClasses:function(e){var i,s,n;for(i in e)n=this.classesElementLookup[i],e[i]!==this.options.classes[i]&&n&&n.length&&(s=t(n.get()),this._removeClass(n,i),s.addClass(this._classes({element:s,keys:i,classes:e,add:!0})))},_setOptionDisabled:function(t){this._toggleClass(this.widget(),this.widgetFullName+"-disabled",null,!!t),t&&(this._removeClass(this.hoverable,null,"ui-state-hover"),this._removeClass(this.focusable,null,"ui-state-focus"))},enable:function(){return this._setOptions({disabled:!1})},disable:function(){return this._setOptions({disabled:!0})},_classes:function(e){function i(i,o){var a,r;for(r=0;i.length>r;r++)a=n.classesElementLookup[i[r]]||t(),a=e.add?t(t.unique(a.get().concat(e.element.get()))):t(a.not(e.element).get()),n.classesElementLookup[i[r]]=a,s.push(i[r]),o&&e.classes[i[r]]&&s.push(e.classes[i[r]])}var s=[],n=this;return e=t.extend({element:this.element,classes:this.options.classes||{}},e),this._on(e.element,{remove:"_untrackClassesElement"}),e.keys&&i(e.keys.match(/\S+/g)||[],!0),e.extra&&i(e.extra.match(/\S+/g)||[]),s.join(" ")},_untrackClassesElement:function(e){var i=this;t.each(i.classesElementLookup,function(s,n){-1!==t.inArray(e.target,n)&&(i.classesElementLookup[s]=t(n.not(e.target).get()))})},_removeClass:function(t,e,i){return this._toggleClass(t,e,i,!1)},_addClass:function(t,e,i){return this._toggleClass(t,e,i,!0)},_toggleClass:function(t,e,i,s){s="boolean"==typeof s?s:i;var n="string"==typeof t||null===t,o={extra:n?e:i,keys:n?t:e,element:n?this.element:t,add:s};return o.element.toggleClass(this._classes(o),s),this},_on:function(e,i,s){var n,o=this;"boolean"!=typeof e&&(s=i,i=e,e=!1),s?(i=n=t(i),this.bindings=this.bindings.add(i)):(s=i,i=this.element,n=this.widget()),t.each(s,function(s,a){function r(){return e||o.options.disabled!==!0&&!t(this).hasClass("ui-state-disabled")?("string"==typeof a?o[a]:a).apply(o,arguments):void 0}"string"!=typeof a&&(r.guid=a.guid=a.guid||r.guid||t.guid++);var h=s.match(/^([\w:-]*)\s*(.*)$/),l=h[1]+o.eventNamespace,c=h[2];c?n.on(l,c,r):i.on(l,r)})},_off:function(e,i){i=(i||"").split(" ").join(this.eventNamespace+" ")+this.eventNamespace,e.off(i).off(i),this.bindings=t(this.bindings.not(e).get()),this.focusable=t(this.focusable.not(e).get()),this.hoverable=t(this.hoverable.not(e).get())},_delay:function(t,e){function i(){return("string"==typeof t?s[t]:t).apply(s,arguments)}var s=this;return setTimeout(i,e||0)},_hoverable:function(e){this.hoverable=this.hoverable.add(e),this._on(e,{mouseenter:function(e){this._addClass(t(e.currentTarget),null,"ui-state-hover")},mouseleave:function(e){this._removeClass(t(e.currentTarget),null,"ui-state-hover")}})},_focusable:function(e){this.focusable=this.focusable.add(e),this._on(e,{focusin:function(e){this._addClass(t(e.currentTarget),null,"ui-state-focus")},focusout:function(e){this._removeClass(t(e.currentTarget),null,"ui-state-focus")}})},_trigger:function(e,i,s){var n,o,a=this.options[e];if(s=s||{},i=t.Event(i),i.type=(e===this.widgetEventPrefix?e:this.widgetEventPrefix+e).toLowerCase(),i.target=this.element[0],o=i.originalEvent)for(n in o)n in i||(i[n]=o[n]);return this.element.trigger(i,s),!(t.isFunction(a)&&a.apply(this.element[0],[i].concat(s))===!1||i.isDefaultPrevented())}},t.each({show:"fadeIn",hide:"fadeOut"},function(e,i){t.Widget.prototype["_"+e]=function(s,n,o){"string"==typeof n&&(n={effect:n});var a,r=n?n===!0||"number"==typeof n?i:n.effect||i:e;n=n||{},"number"==typeof n&&(n={duration:n}),a=!t.isEmptyObject(n),n.complete=o,n.delay&&s.delay(n.delay),a&&t.effects&&t.effects.effect[r]?s[e](n):r!==e&&s[r]?s[r](n.duration,n.easing,o):s.queue(function(i){t(this)[e](),o&&o.call(s[0]),i()})}}),t.widget,function(){function e(t,e,i){return[parseFloat(t[0])*(u.test(t[0])?e/100:1),parseFloat(t[1])*(u.test(t[1])?i/100:1)]}function i(e,i){return parseInt(t.css(e,i),10)||0}function s(e){var i=e[0];return 9===i.nodeType?{width:e.width(),height:e.height(),offset:{top:0,left:0}}:t.isWindow(i)?{width:e.width(),height:e.height(),offset:{top:e.scrollTop(),left:e.scrollLeft()}}:i.preventDefault?{width:0,height:0,offset:{top:i.pageY,left:i.pageX}}:{width:e.outerWidth(),height:e.outerHeight(),offset:e.offset()}}var n,o=Math.max,a=Math.abs,r=/left|center|right/,h=/top|center|bottom/,l=/[\+\-]\d+(\.[\d]+)?%?/,c=/^\w+/,u=/%$/,d=t.fn.position;t.position={scrollbarWidth:function(){if(void 0!==n)return n;var e,i,s=t("
"),o=s.children()[0];return t("body").append(s),e=o.offsetWidth,s.css("overflow","scroll"),i=o.offsetWidth,e===i&&(i=s[0].clientWidth),s.remove(),n=e-i},getScrollInfo:function(e){var i=e.isWindow||e.isDocument?"":e.element.css("overflow-x"),s=e.isWindow||e.isDocument?"":e.element.css("overflow-y"),n="scroll"===i||"auto"===i&&e.widthi?"left":e>0?"right":"center",vertical:0>r?"top":s>0?"bottom":"middle"};l>p&&p>a(e+i)&&(u.horizontal="center"),c>f&&f>a(s+r)&&(u.vertical="middle"),u.important=o(a(e),a(i))>o(a(s),a(r))?"horizontal":"vertical",n.using.call(this,t,u)}),h.offset(t.extend(D,{using:r}))})},t.ui.position={fit:{left:function(t,e){var i,s=e.within,n=s.isWindow?s.scrollLeft:s.offset.left,a=s.width,r=t.left-e.collisionPosition.marginLeft,h=n-r,l=r+e.collisionWidth-a-n;e.collisionWidth>a?h>0&&0>=l?(i=t.left+h+e.collisionWidth-a-n,t.left+=h-i):t.left=l>0&&0>=h?n:h>l?n+a-e.collisionWidth:n:h>0?t.left+=h:l>0?t.left-=l:t.left=o(t.left-r,t.left)},top:function(t,e){var i,s=e.within,n=s.isWindow?s.scrollTop:s.offset.top,a=e.within.height,r=t.top-e.collisionPosition.marginTop,h=n-r,l=r+e.collisionHeight-a-n;e.collisionHeight>a?h>0&&0>=l?(i=t.top+h+e.collisionHeight-a-n,t.top+=h-i):t.top=l>0&&0>=h?n:h>l?n+a-e.collisionHeight:n:h>0?t.top+=h:l>0?t.top-=l:t.top=o(t.top-r,t.top)}},flip:{left:function(t,e){var i,s,n=e.within,o=n.offset.left+n.scrollLeft,r=n.width,h=n.isWindow?n.scrollLeft:n.offset.left,l=t.left-e.collisionPosition.marginLeft,c=l-h,u=l+e.collisionWidth-r-h,d="left"===e.my[0]?-e.elemWidth:"right"===e.my[0]?e.elemWidth:0,p="left"===e.at[0]?e.targetWidth:"right"===e.at[0]?-e.targetWidth:0,f=-2*e.offset[0];0>c?(i=t.left+d+p+f+e.collisionWidth-r-o,(0>i||a(c)>i)&&(t.left+=d+p+f)):u>0&&(s=t.left-e.collisionPosition.marginLeft+d+p+f-h,(s>0||u>a(s))&&(t.left+=d+p+f))},top:function(t,e){var i,s,n=e.within,o=n.offset.top+n.scrollTop,r=n.height,h=n.isWindow?n.scrollTop:n.offset.top,l=t.top-e.collisionPosition.marginTop,c=l-h,u=l+e.collisionHeight-r-h,d="top"===e.my[1],p=d?-e.elemHeight:"bottom"===e.my[1]?e.elemHeight:0,f="top"===e.at[1]?e.targetHeight:"bottom"===e.at[1]?-e.targetHeight:0,m=-2*e.offset[1];0>c?(s=t.top+p+f+m+e.collisionHeight-r-o,(0>s||a(c)>s)&&(t.top+=p+f+m)):u>0&&(i=t.top-e.collisionPosition.marginTop+p+f+m-h,(i>0||u>a(i))&&(t.top+=p+f+m))}},flipfit:{left:function(){t.ui.position.flip.left.apply(this,arguments),t.ui.position.fit.left.apply(this,arguments)},top:function(){t.ui.position.flip.top.apply(this,arguments),t.ui.position.fit.top.apply(this,arguments)}}}}(),t.ui.position,t.extend(t.expr[":"],{data:t.expr.createPseudo?t.expr.createPseudo(function(e){return function(i){return!!t.data(i,e)}}):function(e,i,s){return!!t.data(e,s[3])}}),t.fn.extend({disableSelection:function(){var t="onselectstart"in document.createElement("div")?"selectstart":"mousedown";return function(){return this.on(t+".ui-disableSelection",function(t){t.preventDefault()})}}(),enableSelection:function(){return this.off(".ui-disableSelection")}}),t.ui.focusable=function(i,s){var n,o,a,r,h,l=i.nodeName.toLowerCase();return"area"===l?(n=i.parentNode,o=n.name,i.href&&o&&"map"===n.nodeName.toLowerCase()?(a=t("img[usemap='#"+o+"']"),a.length>0&&a.is(":visible")):!1):(/^(input|select|textarea|button|object)$/.test(l)?(r=!i.disabled,r&&(h=t(i).closest("fieldset")[0],h&&(r=!h.disabled))):r="a"===l?i.href||s:s,r&&t(i).is(":visible")&&e(t(i)))},t.extend(t.expr[":"],{focusable:function(e){return t.ui.focusable(e,null!=t.attr(e,"tabindex"))}}),t.ui.focusable,t.fn.form=function(){return"string"==typeof this[0].form?this.closest("form"):t(this[0].form)},t.ui.formResetMixin={_formResetHandler:function(){var e=t(this);setTimeout(function(){var i=e.data("ui-form-reset-instances");t.each(i,function(){this.refresh()})})},_bindFormResetHandler:function(){if(this.form=this.element.form(),this.form.length){var t=this.form.data("ui-form-reset-instances")||[];t.length||this.form.on("reset.ui-form-reset",this._formResetHandler),t.push(this),this.form.data("ui-form-reset-instances",t)}},_unbindFormResetHandler:function(){if(this.form.length){var e=this.form.data("ui-form-reset-instances");e.splice(t.inArray(this,e),1),e.length?this.form.data("ui-form-reset-instances",e):this.form.removeData("ui-form-reset-instances").off("reset.ui-form-reset")}}},"1.7"===t.fn.jquery.substring(0,3)&&(t.each(["Width","Height"],function(e,i){function s(e,i,s,o){return t.each(n,function(){i-=parseFloat(t.css(e,"padding"+this))||0,s&&(i-=parseFloat(t.css(e,"border"+this+"Width"))||0),o&&(i-=parseFloat(t.css(e,"margin"+this))||0)}),i}var n="Width"===i?["Left","Right"]:["Top","Bottom"],o=i.toLowerCase(),a={innerWidth:t.fn.innerWidth,innerHeight:t.fn.innerHeight,outerWidth:t.fn.outerWidth,outerHeight:t.fn.outerHeight};t.fn["inner"+i]=function(e){return void 0===e?a["inner"+i].call(this):this.each(function(){t(this).css(o,s(this,e)+"px")})},t.fn["outer"+i]=function(e,n){return"number"!=typeof e?a["outer"+i].call(this,e):this.each(function(){t(this).css(o,s(this,e,!0,n)+"px")})}}),t.fn.addBack=function(t){return this.add(null==t?this.prevObject:this.prevObject.filter(t))}),t.ui.keyCode={BACKSPACE:8,COMMA:188,DELETE:46,DOWN:40,END:35,ENTER:13,ESCAPE:27,HOME:36,LEFT:37,PAGE_DOWN:34,PAGE_UP:33,PERIOD:190,RIGHT:39,SPACE:32,TAB:9,UP:38},t.ui.escapeSelector=function(){var t=/([!"#$%&'()*+,./:;<=>?@[\]^`{|}~])/g;return function(e){return e.replace(t,"\\$1")}}(),t.fn.labels=function(){var e,i,s,n,o;return this[0].labels&&this[0].labels.length?this.pushStack(this[0].labels):(n=this.eq(0).parents("label"),s=this.attr("id"),s&&(e=this.eq(0).parents().last(),o=e.add(e.length?e.siblings():this.siblings()),i="label[for='"+t.ui.escapeSelector(s)+"']",n=n.add(o.find(i).addBack(i))),this.pushStack(n))},t.fn.scrollParent=function(e){var i=this.css("position"),s="absolute"===i,n=e?/(auto|scroll|hidden)/:/(auto|scroll)/,o=this.parents().filter(function(){var e=t(this);return s&&"static"===e.css("position")?!1:n.test(e.css("overflow")+e.css("overflow-y")+e.css("overflow-x"))}).eq(0);return"fixed"!==i&&o.length?o:t(this[0].ownerDocument||document)},t.extend(t.expr[":"],{tabbable:function(e){var i=t.attr(e,"tabindex"),s=null!=i;return(!s||i>=0)&&t.ui.focusable(e,s)}}),t.fn.extend({uniqueId:function(){var t=0;return function(){return this.each(function(){this.id||(this.id="ui-id-"+ ++t)})}}(),removeUniqueId:function(){return this.each(function(){/^ui-id-\d+$/.test(this.id)&&t(this).removeAttr("id")})}}),t.ui.ie=!!/msie [\w.]+/.exec(navigator.userAgent.toLowerCase());var n=!1;t(document).on("mouseup",function(){n=!1}),t.widget("ui.mouse",{version:"1.12.1",options:{cancel:"input, textarea, button, select, option",distance:1,delay:0},_mouseInit:function(){var e=this;this.element.on("mousedown."+this.widgetName,function(t){return e._mouseDown(t)}).on("click."+this.widgetName,function(i){return!0===t.data(i.target,e.widgetName+".preventClickEvent")?(t.removeData(i.target,e.widgetName+".preventClickEvent"),i.stopImmediatePropagation(),!1):void 0}),this.started=!1},_mouseDestroy:function(){this.element.off("."+this.widgetName),this._mouseMoveDelegate&&this.document.off("mousemove."+this.widgetName,this._mouseMoveDelegate).off("mouseup."+this.widgetName,this._mouseUpDelegate)},_mouseDown:function(e){if(!n){this._mouseMoved=!1,this._mouseStarted&&this._mouseUp(e),this._mouseDownEvent=e;var i=this,s=1===e.which,o="string"==typeof this.options.cancel&&e.target.nodeName?t(e.target).closest(this.options.cancel).length:!1;return s&&!o&&this._mouseCapture(e)?(this.mouseDelayMet=!this.options.delay,this.mouseDelayMet||(this._mouseDelayTimer=setTimeout(function(){i.mouseDelayMet=!0},this.options.delay)),this._mouseDistanceMet(e)&&this._mouseDelayMet(e)&&(this._mouseStarted=this._mouseStart(e)!==!1,!this._mouseStarted)?(e.preventDefault(),!0):(!0===t.data(e.target,this.widgetName+".preventClickEvent")&&t.removeData(e.target,this.widgetName+".preventClickEvent"),this._mouseMoveDelegate=function(t){return i._mouseMove(t)},this._mouseUpDelegate=function(t){return i._mouseUp(t)},this.document.on("mousemove."+this.widgetName,this._mouseMoveDelegate).on("mouseup."+this.widgetName,this._mouseUpDelegate),e.preventDefault(),n=!0,!0)):!0}},_mouseMove:function(e){if(this._mouseMoved){if(t.ui.ie&&(!document.documentMode||9>document.documentMode)&&!e.button)return this._mouseUp(e);if(!e.which)if(e.originalEvent.altKey||e.originalEvent.ctrlKey||e.originalEvent.metaKey||e.originalEvent.shiftKey)this.ignoreMissingWhich=!0;else if(!this.ignoreMissingWhich)return this._mouseUp(e)}return(e.which||e.button)&&(this._mouseMoved=!0),this._mouseStarted?(this._mouseDrag(e),e.preventDefault()):(this._mouseDistanceMet(e)&&this._mouseDelayMet(e)&&(this._mouseStarted=this._mouseStart(this._mouseDownEvent,e)!==!1,this._mouseStarted?this._mouseDrag(e):this._mouseUp(e)),!this._mouseStarted)},_mouseUp:function(e){this.document.off("mousemove."+this.widgetName,this._mouseMoveDelegate).off("mouseup."+this.widgetName,this._mouseUpDelegate),this._mouseStarted&&(this._mouseStarted=!1,e.target===this._mouseDownEvent.target&&t.data(e.target,this.widgetName+".preventClickEvent",!0),this._mouseStop(e)),this._mouseDelayTimer&&(clearTimeout(this._mouseDelayTimer),delete this._mouseDelayTimer),this.ignoreMissingWhich=!1,n=!1,e.preventDefault()},_mouseDistanceMet:function(t){return Math.max(Math.abs(this._mouseDownEvent.pageX-t.pageX),Math.abs(this._mouseDownEvent.pageY-t.pageY))>=this.options.distance},_mouseDelayMet:function(){return this.mouseDelayMet},_mouseStart:function(){},_mouseDrag:function(){},_mouseStop:function(){},_mouseCapture:function(){return!0}}),t.ui.plugin={add:function(e,i,s){var n,o=t.ui[e].prototype;for(n in s)o.plugins[n]=o.plugins[n]||[],o.plugins[n].push([i,s[n]])},call:function(t,e,i,s){var n,o=t.plugins[e];if(o&&(s||t.element[0].parentNode&&11!==t.element[0].parentNode.nodeType))for(n=0;o.length>n;n++)t.options[o[n][0]]&&o[n][1].apply(t.element,i)}},t.widget("ui.resizable",t.ui.mouse,{version:"1.12.1",widgetEventPrefix:"resize",options:{alsoResize:!1,animate:!1,animateDuration:"slow",animateEasing:"swing",aspectRatio:!1,autoHide:!1,classes:{"ui-resizable-se":"ui-icon ui-icon-gripsmall-diagonal-se"},containment:!1,ghost:!1,grid:!1,handles:"e,s,se",helper:!1,maxHeight:null,maxWidth:null,minHeight:10,minWidth:10,zIndex:90,resize:null,start:null,stop:null},_num:function(t){return parseFloat(t)||0},_isNumber:function(t){return!isNaN(parseFloat(t))},_hasScroll:function(e,i){if("hidden"===t(e).css("overflow"))return!1;var s=i&&"left"===i?"scrollLeft":"scrollTop",n=!1;return e[s]>0?!0:(e[s]=1,n=e[s]>0,e[s]=0,n)},_create:function(){var e,i=this.options,s=this;this._addClass("ui-resizable"),t.extend(this,{_aspectRatio:!!i.aspectRatio,aspectRatio:i.aspectRatio,originalElement:this.element,_proportionallyResizeElements:[],_helper:i.helper||i.ghost||i.animate?i.helper||"ui-resizable-helper":null}),this.element[0].nodeName.match(/^(canvas|textarea|input|select|button|img)$/i)&&(this.element.wrap(t("
").css({position:this.element.css("position"),width:this.element.outerWidth(),height:this.element.outerHeight(),top:this.element.css("top"),left:this.element.css("left")})),this.element=this.element.parent().data("ui-resizable",this.element.resizable("instance")),this.elementIsWrapper=!0,e={marginTop:this.originalElement.css("marginTop"),marginRight:this.originalElement.css("marginRight"),marginBottom:this.originalElement.css("marginBottom"),marginLeft:this.originalElement.css("marginLeft")},this.element.css(e),this.originalElement.css("margin",0),this.originalResizeStyle=this.originalElement.css("resize"),this.originalElement.css("resize","none"),this._proportionallyResizeElements.push(this.originalElement.css({position:"static",zoom:1,display:"block"})),this.originalElement.css(e),this._proportionallyResize()),this._setupHandles(),i.autoHide&&t(this.element).on("mouseenter",function(){i.disabled||(s._removeClass("ui-resizable-autohide"),s._handles.show())}).on("mouseleave",function(){i.disabled||s.resizing||(s._addClass("ui-resizable-autohide"),s._handles.hide())}),this._mouseInit()},_destroy:function(){this._mouseDestroy();var e,i=function(e){t(e).removeData("resizable").removeData("ui-resizable").off(".resizable").find(".ui-resizable-handle").remove()};return this.elementIsWrapper&&(i(this.element),e=this.element,this.originalElement.css({position:e.css("position"),width:e.outerWidth(),height:e.outerHeight(),top:e.css("top"),left:e.css("left")}).insertAfter(e),e.remove()),this.originalElement.css("resize",this.originalResizeStyle),i(this.originalElement),this},_setOption:function(t,e){switch(this._super(t,e),t){case"handles":this._removeHandles(),this._setupHandles();break;default:}},_setupHandles:function(){var e,i,s,n,o,a=this.options,r=this;if(this.handles=a.handles||(t(".ui-resizable-handle",this.element).length?{n:".ui-resizable-n",e:".ui-resizable-e",s:".ui-resizable-s",w:".ui-resizable-w",se:".ui-resizable-se",sw:".ui-resizable-sw",ne:".ui-resizable-ne",nw:".ui-resizable-nw"}:"e,s,se"),this._handles=t(),this.handles.constructor===String)for("all"===this.handles&&(this.handles="n,e,s,w,se,sw,ne,nw"),s=this.handles.split(","),this.handles={},i=0;s.length>i;i++)e=t.trim(s[i]),n="ui-resizable-"+e,o=t("
"),this._addClass(o,"ui-resizable-handle "+n),o.css({zIndex:a.zIndex}),this.handles[e]=".ui-resizable-"+e,this.element.append(o);this._renderAxis=function(e){var i,s,n,o;e=e||this.element;for(i in this.handles)this.handles[i].constructor===String?this.handles[i]=this.element.children(this.handles[i]).first().show():(this.handles[i].jquery||this.handles[i].nodeType)&&(this.handles[i]=t(this.handles[i]),this._on(this.handles[i],{mousedown:r._mouseDown})),this.elementIsWrapper&&this.originalElement[0].nodeName.match(/^(textarea|input|select|button)$/i)&&(s=t(this.handles[i],this.element),o=/sw|ne|nw|se|n|s/.test(i)?s.outerHeight():s.outerWidth(),n=["padding",/ne|nw|n/.test(i)?"Top":/se|sw|s/.test(i)?"Bottom":/^e$/.test(i)?"Right":"Left"].join(""),e.css(n,o),this._proportionallyResize()),this._handles=this._handles.add(this.handles[i])},this._renderAxis(this.element),this._handles=this._handles.add(this.element.find(".ui-resizable-handle")),this._handles.disableSelection(),this._handles.on("mouseover",function(){r.resizing||(this.className&&(o=this.className.match(/ui-resizable-(se|sw|ne|nw|n|e|s|w)/i)),r.axis=o&&o[1]?o[1]:"se")}),a.autoHide&&(this._handles.hide(),this._addClass("ui-resizable-autohide"))},_removeHandles:function(){this._handles.remove()},_mouseCapture:function(e){var i,s,n=!1;for(i in this.handles)s=t(this.handles[i])[0],(s===e.target||t.contains(s,e.target))&&(n=!0);return!this.options.disabled&&n},_mouseStart:function(e){var i,s,n,o=this.options,a=this.element;return this.resizing=!0,this._renderProxy(),i=this._num(this.helper.css("left")),s=this._num(this.helper.css("top")),o.containment&&(i+=t(o.containment).scrollLeft()||0,s+=t(o.containment).scrollTop()||0),this.offset=this.helper.offset(),this.position={left:i,top:s},this.size=this._helper?{width:this.helper.width(),height:this.helper.height()}:{width:a.width(),height:a.height()},this.originalSize=this._helper?{width:a.outerWidth(),height:a.outerHeight()}:{width:a.width(),height:a.height()},this.sizeDiff={width:a.outerWidth()-a.width(),height:a.outerHeight()-a.height()},this.originalPosition={left:i,top:s},this.originalMousePosition={left:e.pageX,top:e.pageY},this.aspectRatio="number"==typeof o.aspectRatio?o.aspectRatio:this.originalSize.width/this.originalSize.height||1,n=t(".ui-resizable-"+this.axis).css("cursor"),t("body").css("cursor","auto"===n?this.axis+"-resize":n),this._addClass("ui-resizable-resizing"),this._propagate("start",e),!0},_mouseDrag:function(e){var i,s,n=this.originalMousePosition,o=this.axis,a=e.pageX-n.left||0,r=e.pageY-n.top||0,h=this._change[o];return this._updatePrevProperties(),h?(i=h.apply(this,[e,a,r]),this._updateVirtualBoundaries(e.shiftKey),(this._aspectRatio||e.shiftKey)&&(i=this._updateRatio(i,e)),i=this._respectSize(i,e),this._updateCache(i),this._propagate("resize",e),s=this._applyChanges(),!this._helper&&this._proportionallyResizeElements.length&&this._proportionallyResize(),t.isEmptyObject(s)||(this._updatePrevProperties(),this._trigger("resize",e,this.ui()),this._applyChanges()),!1):!1},_mouseStop:function(e){this.resizing=!1;var i,s,n,o,a,r,h,l=this.options,c=this;return this._helper&&(i=this._proportionallyResizeElements,s=i.length&&/textarea/i.test(i[0].nodeName),n=s&&this._hasScroll(i[0],"left")?0:c.sizeDiff.height,o=s?0:c.sizeDiff.width,a={width:c.helper.width()-o,height:c.helper.height()-n},r=parseFloat(c.element.css("left"))+(c.position.left-c.originalPosition.left)||null,h=parseFloat(c.element.css("top"))+(c.position.top-c.originalPosition.top)||null,l.animate||this.element.css(t.extend(a,{top:h,left:r})),c.helper.height(c.size.height),c.helper.width(c.size.width),this._helper&&!l.animate&&this._proportionallyResize()),t("body").css("cursor","auto"),this._removeClass("ui-resizable-resizing"),this._propagate("stop",e),this._helper&&this.helper.remove(),!1},_updatePrevProperties:function(){this.prevPosition={top:this.position.top,left:this.position.left},this.prevSize={width:this.size.width,height:this.size.height}},_applyChanges:function(){var t={};return this.position.top!==this.prevPosition.top&&(t.top=this.position.top+"px"),this.position.left!==this.prevPosition.left&&(t.left=this.position.left+"px"),this.size.width!==this.prevSize.width&&(t.width=this.size.width+"px"),this.size.height!==this.prevSize.height&&(t.height=this.size.height+"px"),this.helper.css(t),t},_updateVirtualBoundaries:function(t){var e,i,s,n,o,a=this.options;o={minWidth:this._isNumber(a.minWidth)?a.minWidth:0,maxWidth:this._isNumber(a.maxWidth)?a.maxWidth:1/0,minHeight:this._isNumber(a.minHeight)?a.minHeight:0,maxHeight:this._isNumber(a.maxHeight)?a.maxHeight:1/0},(this._aspectRatio||t)&&(e=o.minHeight*this.aspectRatio,s=o.minWidth/this.aspectRatio,i=o.maxHeight*this.aspectRatio,n=o.maxWidth/this.aspectRatio,e>o.minWidth&&(o.minWidth=e),s>o.minHeight&&(o.minHeight=s),o.maxWidth>i&&(o.maxWidth=i),o.maxHeight>n&&(o.maxHeight=n)),this._vBoundaries=o},_updateCache:function(t){this.offset=this.helper.offset(),this._isNumber(t.left)&&(this.position.left=t.left),this._isNumber(t.top)&&(this.position.top=t.top),this._isNumber(t.height)&&(this.size.height=t.height),this._isNumber(t.width)&&(this.size.width=t.width)},_updateRatio:function(t){var e=this.position,i=this.size,s=this.axis;return this._isNumber(t.height)?t.width=t.height*this.aspectRatio:this._isNumber(t.width)&&(t.height=t.width/this.aspectRatio),"sw"===s&&(t.left=e.left+(i.width-t.width),t.top=null),"nw"===s&&(t.top=e.top+(i.height-t.height),t.left=e.left+(i.width-t.width)),t},_respectSize:function(t){var e=this._vBoundaries,i=this.axis,s=this._isNumber(t.width)&&e.maxWidth&&e.maxWidtht.width,a=this._isNumber(t.height)&&e.minHeight&&e.minHeight>t.height,r=this.originalPosition.left+this.originalSize.width,h=this.originalPosition.top+this.originalSize.height,l=/sw|nw|w/.test(i),c=/nw|ne|n/.test(i);return o&&(t.width=e.minWidth),a&&(t.height=e.minHeight),s&&(t.width=e.maxWidth),n&&(t.height=e.maxHeight),o&&l&&(t.left=r-e.minWidth),s&&l&&(t.left=r-e.maxWidth),a&&c&&(t.top=h-e.minHeight),n&&c&&(t.top=h-e.maxHeight),t.width||t.height||t.left||!t.top?t.width||t.height||t.top||!t.left||(t.left=null):t.top=null,t},_getPaddingPlusBorderDimensions:function(t){for(var e=0,i=[],s=[t.css("borderTopWidth"),t.css("borderRightWidth"),t.css("borderBottomWidth"),t.css("borderLeftWidth")],n=[t.css("paddingTop"),t.css("paddingRight"),t.css("paddingBottom"),t.css("paddingLeft")];4>e;e++)i[e]=parseFloat(s[e])||0,i[e]+=parseFloat(n[e])||0;return{height:i[0]+i[2],width:i[1]+i[3]}},_proportionallyResize:function(){if(this._proportionallyResizeElements.length)for(var t,e=0,i=this.helper||this.element;this._proportionallyResizeElements.length>e;e++)t=this._proportionallyResizeElements[e],this.outerDimensions||(this.outerDimensions=this._getPaddingPlusBorderDimensions(t)),t.css({height:i.height()-this.outerDimensions.height||0,width:i.width()-this.outerDimensions.width||0})},_renderProxy:function(){var e=this.element,i=this.options;this.elementOffset=e.offset(),this._helper?(this.helper=this.helper||t("
"),this._addClass(this.helper,this._helper),this.helper.css({width:this.element.outerWidth(),height:this.element.outerHeight(),position:"absolute",left:this.elementOffset.left+"px",top:this.elementOffset.top+"px",zIndex:++i.zIndex}),this.helper.appendTo("body").disableSelection()):this.helper=this.element -},_change:{e:function(t,e){return{width:this.originalSize.width+e}},w:function(t,e){var i=this.originalSize,s=this.originalPosition;return{left:s.left+e,width:i.width-e}},n:function(t,e,i){var s=this.originalSize,n=this.originalPosition;return{top:n.top+i,height:s.height-i}},s:function(t,e,i){return{height:this.originalSize.height+i}},se:function(e,i,s){return t.extend(this._change.s.apply(this,arguments),this._change.e.apply(this,[e,i,s]))},sw:function(e,i,s){return t.extend(this._change.s.apply(this,arguments),this._change.w.apply(this,[e,i,s]))},ne:function(e,i,s){return t.extend(this._change.n.apply(this,arguments),this._change.e.apply(this,[e,i,s]))},nw:function(e,i,s){return t.extend(this._change.n.apply(this,arguments),this._change.w.apply(this,[e,i,s]))}},_propagate:function(e,i){t.ui.plugin.call(this,e,[i,this.ui()]),"resize"!==e&&this._trigger(e,i,this.ui())},plugins:{},ui:function(){return{originalElement:this.originalElement,element:this.element,helper:this.helper,position:this.position,size:this.size,originalSize:this.originalSize,originalPosition:this.originalPosition}}}),t.ui.plugin.add("resizable","animate",{stop:function(e){var i=t(this).resizable("instance"),s=i.options,n=i._proportionallyResizeElements,o=n.length&&/textarea/i.test(n[0].nodeName),a=o&&i._hasScroll(n[0],"left")?0:i.sizeDiff.height,r=o?0:i.sizeDiff.width,h={width:i.size.width-r,height:i.size.height-a},l=parseFloat(i.element.css("left"))+(i.position.left-i.originalPosition.left)||null,c=parseFloat(i.element.css("top"))+(i.position.top-i.originalPosition.top)||null;i.element.animate(t.extend(h,c&&l?{top:c,left:l}:{}),{duration:s.animateDuration,easing:s.animateEasing,step:function(){var s={width:parseFloat(i.element.css("width")),height:parseFloat(i.element.css("height")),top:parseFloat(i.element.css("top")),left:parseFloat(i.element.css("left"))};n&&n.length&&t(n[0]).css({width:s.width,height:s.height}),i._updateCache(s),i._propagate("resize",e)}})}}),t.ui.plugin.add("resizable","containment",{start:function(){var e,i,s,n,o,a,r,h=t(this).resizable("instance"),l=h.options,c=h.element,u=l.containment,d=u instanceof t?u.get(0):/parent/.test(u)?c.parent().get(0):u;d&&(h.containerElement=t(d),/document/.test(u)||u===document?(h.containerOffset={left:0,top:0},h.containerPosition={left:0,top:0},h.parentData={element:t(document),left:0,top:0,width:t(document).width(),height:t(document).height()||document.body.parentNode.scrollHeight}):(e=t(d),i=[],t(["Top","Right","Left","Bottom"]).each(function(t,s){i[t]=h._num(e.css("padding"+s))}),h.containerOffset=e.offset(),h.containerPosition=e.position(),h.containerSize={height:e.innerHeight()-i[3],width:e.innerWidth()-i[1]},s=h.containerOffset,n=h.containerSize.height,o=h.containerSize.width,a=h._hasScroll(d,"left")?d.scrollWidth:o,r=h._hasScroll(d)?d.scrollHeight:n,h.parentData={element:d,left:s.left,top:s.top,width:a,height:r}))},resize:function(e){var i,s,n,o,a=t(this).resizable("instance"),r=a.options,h=a.containerOffset,l=a.position,c=a._aspectRatio||e.shiftKey,u={top:0,left:0},d=a.containerElement,p=!0;d[0]!==document&&/static/.test(d.css("position"))&&(u=h),l.left<(a._helper?h.left:0)&&(a.size.width=a.size.width+(a._helper?a.position.left-h.left:a.position.left-u.left),c&&(a.size.height=a.size.width/a.aspectRatio,p=!1),a.position.left=r.helper?h.left:0),l.top<(a._helper?h.top:0)&&(a.size.height=a.size.height+(a._helper?a.position.top-h.top:a.position.top),c&&(a.size.width=a.size.height*a.aspectRatio,p=!1),a.position.top=a._helper?h.top:0),n=a.containerElement.get(0)===a.element.parent().get(0),o=/relative|absolute/.test(a.containerElement.css("position")),n&&o?(a.offset.left=a.parentData.left+a.position.left,a.offset.top=a.parentData.top+a.position.top):(a.offset.left=a.element.offset().left,a.offset.top=a.element.offset().top),i=Math.abs(a.sizeDiff.width+(a._helper?a.offset.left-u.left:a.offset.left-h.left)),s=Math.abs(a.sizeDiff.height+(a._helper?a.offset.top-u.top:a.offset.top-h.top)),i+a.size.width>=a.parentData.width&&(a.size.width=a.parentData.width-i,c&&(a.size.height=a.size.width/a.aspectRatio,p=!1)),s+a.size.height>=a.parentData.height&&(a.size.height=a.parentData.height-s,c&&(a.size.width=a.size.height*a.aspectRatio,p=!1)),p||(a.position.left=a.prevPosition.left,a.position.top=a.prevPosition.top,a.size.width=a.prevSize.width,a.size.height=a.prevSize.height)},stop:function(){var e=t(this).resizable("instance"),i=e.options,s=e.containerOffset,n=e.containerPosition,o=e.containerElement,a=t(e.helper),r=a.offset(),h=a.outerWidth()-e.sizeDiff.width,l=a.outerHeight()-e.sizeDiff.height;e._helper&&!i.animate&&/relative/.test(o.css("position"))&&t(this).css({left:r.left-n.left-s.left,width:h,height:l}),e._helper&&!i.animate&&/static/.test(o.css("position"))&&t(this).css({left:r.left-n.left-s.left,width:h,height:l})}}),t.ui.plugin.add("resizable","alsoResize",{start:function(){var e=t(this).resizable("instance"),i=e.options;t(i.alsoResize).each(function(){var e=t(this);e.data("ui-resizable-alsoresize",{width:parseFloat(e.width()),height:parseFloat(e.height()),left:parseFloat(e.css("left")),top:parseFloat(e.css("top"))})})},resize:function(e,i){var s=t(this).resizable("instance"),n=s.options,o=s.originalSize,a=s.originalPosition,r={height:s.size.height-o.height||0,width:s.size.width-o.width||0,top:s.position.top-a.top||0,left:s.position.left-a.left||0};t(n.alsoResize).each(function(){var e=t(this),s=t(this).data("ui-resizable-alsoresize"),n={},o=e.parents(i.originalElement[0]).length?["width","height"]:["width","height","top","left"];t.each(o,function(t,e){var i=(s[e]||0)+(r[e]||0);i&&i>=0&&(n[e]=i||null)}),e.css(n)})},stop:function(){t(this).removeData("ui-resizable-alsoresize")}}),t.ui.plugin.add("resizable","ghost",{start:function(){var e=t(this).resizable("instance"),i=e.size;e.ghost=e.originalElement.clone(),e.ghost.css({opacity:.25,display:"block",position:"relative",height:i.height,width:i.width,margin:0,left:0,top:0}),e._addClass(e.ghost,"ui-resizable-ghost"),t.uiBackCompat!==!1&&"string"==typeof e.options.ghost&&e.ghost.addClass(this.options.ghost),e.ghost.appendTo(e.helper)},resize:function(){var e=t(this).resizable("instance");e.ghost&&e.ghost.css({position:"relative",height:e.size.height,width:e.size.width})},stop:function(){var e=t(this).resizable("instance");e.ghost&&e.helper&&e.helper.get(0).removeChild(e.ghost.get(0))}}),t.ui.plugin.add("resizable","grid",{resize:function(){var e,i=t(this).resizable("instance"),s=i.options,n=i.size,o=i.originalSize,a=i.originalPosition,r=i.axis,h="number"==typeof s.grid?[s.grid,s.grid]:s.grid,l=h[0]||1,c=h[1]||1,u=Math.round((n.width-o.width)/l)*l,d=Math.round((n.height-o.height)/c)*c,p=o.width+u,f=o.height+d,m=s.maxWidth&&p>s.maxWidth,g=s.maxHeight&&f>s.maxHeight,_=s.minWidth&&s.minWidth>p,v=s.minHeight&&s.minHeight>f;s.grid=h,_&&(p+=l),v&&(f+=c),m&&(p-=l),g&&(f-=c),/^(se|s|e)$/.test(r)?(i.size.width=p,i.size.height=f):/^(ne)$/.test(r)?(i.size.width=p,i.size.height=f,i.position.top=a.top-d):/^(sw)$/.test(r)?(i.size.width=p,i.size.height=f,i.position.left=a.left-u):((0>=f-c||0>=p-l)&&(e=i._getPaddingPlusBorderDimensions(this)),f-c>0?(i.size.height=f,i.position.top=a.top-d):(f=c-e.height,i.size.height=f,i.position.top=a.top+o.height-f),p-l>0?(i.size.width=p,i.position.left=a.left-u):(p=l-e.width,i.size.width=p,i.position.left=a.left+o.width-p))}}),t.ui.resizable});/** - * Copyright (c) 2007 Ariel Flesler - aflesler ○ gmail • com | https://github.com/flesler - * Licensed under MIT - * @author Ariel Flesler - * @version 2.1.2 - */ -;(function(f){"use strict";"function"===typeof define&&define.amd?define(["jquery"],f):"undefined"!==typeof module&&module.exports?module.exports=f(require("jquery")):f(jQuery)})(function($){"use strict";function n(a){return!a.nodeName||-1!==$.inArray(a.nodeName.toLowerCase(),["iframe","#document","html","body"])}function h(a){return $.isFunction(a)||$.isPlainObject(a)?a:{top:a,left:a}}var p=$.scrollTo=function(a,d,b){return $(window).scrollTo(a,d,b)};p.defaults={axis:"xy",duration:0,limit:!0};$.fn.scrollTo=function(a,d,b){"object"=== typeof d&&(b=d,d=0);"function"===typeof b&&(b={onAfter:b});"max"===a&&(a=9E9);b=$.extend({},p.defaults,b);d=d||b.duration;var u=b.queue&&1=f[g]?0:Math.min(f[g],n));!a&&1)[^>]*$|#([\w\-]*)$)/,bM=/\S/,bI=/^\s+/,bE=/\s+$/,bA=/^<(\w+)\s*\/?>(?:<\/\1>)?$/,bN=/^[\],:{}\s]*$/,bW=/\\(?:["\\\/bfnrt]|u[0-9a-fA-F]{4})/g,bP=/"[^"\\\n\r]*"|true|false|null|-?\d+(?:\.\d*)?(?:[eE][+\-]?\d+)?/g,bJ=/(?:^|:|,)(?:\s*\[)+/g,by=/(webkit)[ \/]([\w.]+)/,bR=/(opera)(?:.*version)?[ \/]([\w.]+)/,bQ=/(msie) ([\w.]+)/,bS=/(mozilla)(?:.*? rv:([\w.]+))?/,bB=/-([a-z]|[0-9])/ig,bZ=/^-ms-/,bT=function(b0,b1){return(b1+"").toUpperCase()},bX=bu.userAgent,bV,bC,e,bL=Object.prototype.toString,bG=Object.prototype.hasOwnProperty,bz=Array.prototype.push,bK=Array.prototype.slice,bO=String.prototype.trim,bv=Array.prototype.indexOf,bx={};bF.fn=bF.prototype={constructor:bF,init:function(b0,b4,b3){var b2,b5,b1,b6;if(!b0){return this}if(b0.nodeType){this.context=this[0]=b0;this.length=1;return this}if(b0==="body"&&!b4&&av.body){this.context=av;this[0]=av.body;this.selector=b0;this.length=1;return this}if(typeof b0==="string"){if(b0.charAt(0)==="<"&&b0.charAt(b0.length-1)===">"&&b0.length>=3){b2=[null,b0,null]}else{b2=bY.exec(b0)}if(b2&&(b2[1]||!b4)){if(b2[1]){b4=b4 instanceof bF?b4[0]:b4;b6=(b4?b4.ownerDocument||b4:av);b1=bA.exec(b0);if(b1){if(bF.isPlainObject(b4)){b0=[av.createElement(b1[1])];bF.fn.attr.call(b0,b4,true)}else{b0=[b6.createElement(b1[1])]}}else{b1=bF.buildFragment([b2[1]],[b6]);b0=(b1.cacheable?bF.clone(b1.fragment):b1.fragment).childNodes}return bF.merge(this,b0)}else{b5=av.getElementById(b2[2]);if(b5&&b5.parentNode){if(b5.id!==b2[2]){return b3.find(b0)}this.length=1;this[0]=b5}this.context=av;this.selector=b0;return this}}else{if(!b4||b4.jquery){return(b4||b3).find(b0)}else{return this.constructor(b4).find(b0)}}}else{if(bF.isFunction(b0)){return b3.ready(b0)}}if(b0.selector!==L){this.selector=b0.selector;this.context=b0.context}return bF.makeArray(b0,this)},selector:"",jquery:"1.7.1",length:0,size:function(){return this.length},toArray:function(){return bK.call(this,0)},get:function(b0){return b0==null?this.toArray():(b0<0?this[this.length+b0]:this[b0])},pushStack:function(b1,b3,b0){var b2=this.constructor();if(bF.isArray(b1)){bz.apply(b2,b1)}else{bF.merge(b2,b1)}b2.prevObject=this;b2.context=this.context;if(b3==="find"){b2.selector=this.selector+(this.selector?" ":"")+b0}else{if(b3){b2.selector=this.selector+"."+b3+"("+b0+")"}}return b2},each:function(b1,b0){return bF.each(this,b1,b0)},ready:function(b0){bF.bindReady();bC.add(b0);return this},eq:function(b0){b0=+b0;return b0===-1?this.slice(b0):this.slice(b0,b0+1)},first:function(){return this.eq(0)},last:function(){return this.eq(-1)},slice:function(){return this.pushStack(bK.apply(this,arguments),"slice",bK.call(arguments).join(","))},map:function(b0){return this.pushStack(bF.map(this,function(b2,b1){return b0.call(b2,b1,b2)}))},end:function(){return this.prevObject||this.constructor(null)},push:bz,sort:[].sort,splice:[].splice};bF.fn.init.prototype=bF.fn;bF.extend=bF.fn.extend=function(){var b9,b2,b0,b1,b6,b7,b5=arguments[0]||{},b4=1,b3=arguments.length,b8=false;if(typeof b5==="boolean"){b8=b5;b5=arguments[1]||{};b4=2}if(typeof b5!=="object"&&!bF.isFunction(b5)){b5={}}if(b3===b4){b5=this;--b4}for(;b40){return}bC.fireWith(av,[bF]);if(bF.fn.trigger){bF(av).trigger("ready").off("ready")}}},bindReady:function(){if(bC){return}bC=bF.Callbacks("once memory");if(av.readyState==="complete"){return setTimeout(bF.ready,1)}if(av.addEventListener){av.addEventListener("DOMContentLoaded",e,false);bb.addEventListener("load",bF.ready,false)}else{if(av.attachEvent){av.attachEvent("onreadystatechange",e);bb.attachEvent("onload",bF.ready);var b0=false;try{b0=bb.frameElement==null}catch(b1){}if(av.documentElement.doScroll&&b0){bw()}}}},isFunction:function(b0){return bF.type(b0)==="function"},isArray:Array.isArray||function(b0){return bF.type(b0)==="array"},isWindow:function(b0){return b0&&typeof b0==="object"&&"setInterval" in b0},isNumeric:function(b0){return !isNaN(parseFloat(b0))&&isFinite(b0)},type:function(b0){return b0==null?String(b0):bx[bL.call(b0)]||"object"},isPlainObject:function(b2){if(!b2||bF.type(b2)!=="object"||b2.nodeType||bF.isWindow(b2)){return false}try{if(b2.constructor&&!bG.call(b2,"constructor")&&!bG.call(b2.constructor.prototype,"isPrototypeOf")){return false}}catch(b1){return false}var b0;for(b0 in b2){}return b0===L||bG.call(b2,b0)},isEmptyObject:function(b1){for(var b0 in b1){return false}return true},error:function(b0){throw new Error(b0)},parseJSON:function(b0){if(typeof b0!=="string"||!b0){return null}b0=bF.trim(b0);if(bb.JSON&&bb.JSON.parse){return bb.JSON.parse(b0)}if(bN.test(b0.replace(bW,"@").replace(bP,"]").replace(bJ,""))){return(new Function("return "+b0))()}bF.error("Invalid JSON: "+b0)},parseXML:function(b2){var b0,b1;try{if(bb.DOMParser){b1=new DOMParser();b0=b1.parseFromString(b2,"text/xml")}else{b0=new ActiveXObject("Microsoft.XMLDOM");b0.async="false";b0.loadXML(b2)}}catch(b3){b0=L}if(!b0||!b0.documentElement||b0.getElementsByTagName("parsererror").length){bF.error("Invalid XML: "+b2)}return b0},noop:function(){},globalEval:function(b0){if(b0&&bM.test(b0)){(bb.execScript||function(b1){bb["eval"].call(bb,b1)})(b0)}},camelCase:function(b0){return b0.replace(bZ,"ms-").replace(bB,bT)},nodeName:function(b1,b0){return b1.nodeName&&b1.nodeName.toUpperCase()===b0.toUpperCase()},each:function(b3,b6,b2){var b1,b4=0,b5=b3.length,b0=b5===L||bF.isFunction(b3);if(b2){if(b0){for(b1 in b3){if(b6.apply(b3[b1],b2)===false){break}}}else{for(;b40&&b0[0]&&b0[b1-1])||b1===0||bF.isArray(b0));if(b3){for(;b21?aJ.call(arguments,0):bG;if(!(--bw)){bC.resolveWith(bC,bx)}}}function bz(bF){return function(bG){bB[bF]=arguments.length>1?aJ.call(arguments,0):bG;bC.notifyWith(bE,bB)}}if(e>1){for(;bv
a";bI=bv.getElementsByTagName("*");bF=bv.getElementsByTagName("a")[0];if(!bI||!bI.length||!bF){return{}}bG=av.createElement("select");bx=bG.appendChild(av.createElement("option"));bE=bv.getElementsByTagName("input")[0];bJ={leadingWhitespace:(bv.firstChild.nodeType===3),tbody:!bv.getElementsByTagName("tbody").length,htmlSerialize:!!bv.getElementsByTagName("link").length,style:/top/.test(bF.getAttribute("style")),hrefNormalized:(bF.getAttribute("href")==="/a"),opacity:/^0.55/.test(bF.style.opacity),cssFloat:!!bF.style.cssFloat,checkOn:(bE.value==="on"),optSelected:bx.selected,getSetAttribute:bv.className!=="t",enctype:!!av.createElement("form").enctype,html5Clone:av.createElement("nav").cloneNode(true).outerHTML!=="<:nav>",submitBubbles:true,changeBubbles:true,focusinBubbles:false,deleteExpando:true,noCloneEvent:true,inlineBlockNeedsLayout:false,shrinkWrapBlocks:false,reliableMarginRight:true};bE.checked=true;bJ.noCloneChecked=bE.cloneNode(true).checked;bG.disabled=true;bJ.optDisabled=!bx.disabled;try{delete bv.test}catch(bC){bJ.deleteExpando=false}if(!bv.addEventListener&&bv.attachEvent&&bv.fireEvent){bv.attachEvent("onclick",function(){bJ.noCloneEvent=false});bv.cloneNode(true).fireEvent("onclick")}bE=av.createElement("input");bE.value="t";bE.setAttribute("type","radio");bJ.radioValue=bE.value==="t";bE.setAttribute("checked","checked");bv.appendChild(bE);bD=av.createDocumentFragment();bD.appendChild(bv.lastChild);bJ.checkClone=bD.cloneNode(true).cloneNode(true).lastChild.checked;bJ.appendChecked=bE.checked;bD.removeChild(bE);bD.appendChild(bv);bv.innerHTML="";if(bb.getComputedStyle){bA=av.createElement("div");bA.style.width="0";bA.style.marginRight="0";bv.style.width="2px";bv.appendChild(bA);bJ.reliableMarginRight=(parseInt((bb.getComputedStyle(bA,null)||{marginRight:0}).marginRight,10)||0)===0}if(bv.attachEvent){for(by in {submit:1,change:1,focusin:1}){bB="on"+by;bw=(bB in bv);if(!bw){bv.setAttribute(bB,"return;");bw=(typeof bv[bB]==="function")}bJ[by+"Bubbles"]=bw}}bD.removeChild(bv);bD=bG=bx=bA=bv=bE=null;b(function(){var bM,bU,bV,bT,bN,bO,bL,bS,bR,e,bP,bQ=av.getElementsByTagName("body")[0];if(!bQ){return}bL=1;bS="position:absolute;top:0;left:0;width:1px;height:1px;margin:0;";bR="visibility:hidden;border:0;";e="style='"+bS+"border:5px solid #000;padding:0;'";bP="
";bM=av.createElement("div");bM.style.cssText=bR+"width:0;height:0;position:static;top:0;margin-top:"+bL+"px";bQ.insertBefore(bM,bQ.firstChild);bv=av.createElement("div");bM.appendChild(bv);bv.innerHTML="
t
";bz=bv.getElementsByTagName("td");bw=(bz[0].offsetHeight===0);bz[0].style.display="";bz[1].style.display="none";bJ.reliableHiddenOffsets=bw&&(bz[0].offsetHeight===0);bv.innerHTML="";bv.style.width=bv.style.paddingLeft="1px";b.boxModel=bJ.boxModel=bv.offsetWidth===2;if(typeof bv.style.zoom!=="undefined"){bv.style.display="inline";bv.style.zoom=1;bJ.inlineBlockNeedsLayout=(bv.offsetWidth===2);bv.style.display="";bv.innerHTML="
";bJ.shrinkWrapBlocks=(bv.offsetWidth!==2)}bv.style.cssText=bS+bR;bv.innerHTML=bP;bU=bv.firstChild;bV=bU.firstChild;bN=bU.nextSibling.firstChild.firstChild;bO={doesNotAddBorder:(bV.offsetTop!==5),doesAddBorderForTableAndCells:(bN.offsetTop===5)};bV.style.position="fixed";bV.style.top="20px";bO.fixedPosition=(bV.offsetTop===20||bV.offsetTop===15);bV.style.position=bV.style.top="";bU.style.overflow="hidden";bU.style.position="relative";bO.subtractsBorderForOverflowNotVisible=(bV.offsetTop===-5);bO.doesNotIncludeMarginInBodyOffset=(bQ.offsetTop!==bL);bQ.removeChild(bM);bv=bM=null;b.extend(bJ,bO)});return bJ})();var aS=/^(?:\{.*\}|\[.*\])$/,aA=/([A-Z])/g;b.extend({cache:{},uuid:0,expando:"jQuery"+(b.fn.jquery+Math.random()).replace(/\D/g,""),noData:{embed:true,object:"clsid:D27CDB6E-AE6D-11cf-96B8-444553540000",applet:true},hasData:function(e){e=e.nodeType?b.cache[e[b.expando]]:e[b.expando];return !!e&&!S(e)},data:function(bx,bv,bz,by){if(!b.acceptData(bx)){return}var bG,bA,bD,bE=b.expando,bC=typeof bv==="string",bF=bx.nodeType,e=bF?b.cache:bx,bw=bF?bx[bE]:bx[bE]&&bE,bB=bv==="events";if((!bw||!e[bw]||(!bB&&!by&&!e[bw].data))&&bC&&bz===L){return}if(!bw){if(bF){bx[bE]=bw=++b.uuid}else{bw=bE}}if(!e[bw]){e[bw]={};if(!bF){e[bw].toJSON=b.noop}}if(typeof bv==="object"||typeof bv==="function"){if(by){e[bw]=b.extend(e[bw],bv)}else{e[bw].data=b.extend(e[bw].data,bv)}}bG=bA=e[bw];if(!by){if(!bA.data){bA.data={}}bA=bA.data}if(bz!==L){bA[b.camelCase(bv)]=bz}if(bB&&!bA[bv]){return bG.events}if(bC){bD=bA[bv];if(bD==null){bD=bA[b.camelCase(bv)]}}else{bD=bA}return bD},removeData:function(bx,bv,by){if(!b.acceptData(bx)){return}var bB,bA,bz,bC=b.expando,bD=bx.nodeType,e=bD?b.cache:bx,bw=bD?bx[bC]:bC;if(!e[bw]){return}if(bv){bB=by?e[bw]:e[bw].data;if(bB){if(!b.isArray(bv)){if(bv in bB){bv=[bv]}else{bv=b.camelCase(bv);if(bv in bB){bv=[bv]}else{bv=bv.split(" ")}}}for(bA=0,bz=bv.length;bA-1){return true}}return false},val:function(bx){var e,bv,by,bw=this[0];if(!arguments.length){if(bw){e=b.valHooks[bw.nodeName.toLowerCase()]||b.valHooks[bw.type];if(e&&"get" in e&&(bv=e.get(bw,"value"))!==L){return bv}bv=bw.value;return typeof bv==="string"?bv.replace(aU,""):bv==null?"":bv}return}by=b.isFunction(bx);return this.each(function(bA){var bz=b(this),bB;if(this.nodeType!==1){return}if(by){bB=bx.call(this,bA,bz.val())}else{bB=bx}if(bB==null){bB=""}else{if(typeof bB==="number"){bB+=""}else{if(b.isArray(bB)){bB=b.map(bB,function(bC){return bC==null?"":bC+""})}}}e=b.valHooks[this.nodeName.toLowerCase()]||b.valHooks[this.type];if(!e||!("set" in e)||e.set(this,bB,"value")===L){this.value=bB}})}});b.extend({valHooks:{option:{get:function(e){var bv=e.attributes.value;return !bv||bv.specified?e.value:e.text}},select:{get:function(e){var bA,bv,bz,bx,by=e.selectedIndex,bB=[],bC=e.options,bw=e.type==="select-one";if(by<0){return null}bv=bw?by:0;bz=bw?by+1:bC.length;for(;bv=0});if(!e.length){bv.selectedIndex=-1}return e}}},attrFn:{val:true,css:true,html:true,text:true,data:true,width:true,height:true,offset:true},attr:function(bA,bx,bB,bz){var bw,e,by,bv=bA.nodeType;if(!bA||bv===3||bv===8||bv===2){return}if(bz&&bx in b.attrFn){return b(bA)[bx](bB)}if(typeof bA.getAttribute==="undefined"){return b.prop(bA,bx,bB)}by=bv!==1||!b.isXMLDoc(bA);if(by){bx=bx.toLowerCase();e=b.attrHooks[bx]||(ao.test(bx)?aY:be)}if(bB!==L){if(bB===null){b.removeAttr(bA,bx);return}else{if(e&&"set" in e&&by&&(bw=e.set(bA,bB,bx))!==L){return bw}else{bA.setAttribute(bx,""+bB);return bB}}}else{if(e&&"get" in e&&by&&(bw=e.get(bA,bx))!==null){return bw}else{bw=bA.getAttribute(bx);return bw===null?L:bw}}},removeAttr:function(bx,bz){var by,bA,bv,e,bw=0;if(bz&&bx.nodeType===1){bA=bz.toLowerCase().split(af);e=bA.length;for(;bw=0)}}})});var bd=/^(?:textarea|input|select)$/i,n=/^([^\.]*)?(?:\.(.+))?$/,J=/\bhover(\.\S+)?\b/,aO=/^key/,bf=/^(?:mouse|contextmenu)|click/,T=/^(?:focusinfocus|focusoutblur)$/,U=/^(\w*)(?:#([\w\-]+))?(?:\.([\w\-]+))?$/,Y=function(e){var bv=U.exec(e);if(bv){bv[1]=(bv[1]||"").toLowerCase();bv[3]=bv[3]&&new RegExp("(?:^|\\s)"+bv[3]+"(?:\\s|$)")}return bv},j=function(bw,e){var bv=bw.attributes||{};return((!e[1]||bw.nodeName.toLowerCase()===e[1])&&(!e[2]||(bv.id||{}).value===e[2])&&(!e[3]||e[3].test((bv["class"]||{}).value)))},bt=function(e){return b.event.special.hover?e:e.replace(J,"mouseenter$1 mouseleave$1")};b.event={add:function(bx,bC,bJ,bA,by){var bD,bB,bK,bI,bH,bF,e,bG,bv,bz,bw,bE;if(bx.nodeType===3||bx.nodeType===8||!bC||!bJ||!(bD=b._data(bx))){return}if(bJ.handler){bv=bJ;bJ=bv.handler}if(!bJ.guid){bJ.guid=b.guid++}bK=bD.events;if(!bK){bD.events=bK={}}bB=bD.handle;if(!bB){bD.handle=bB=function(bL){return typeof b!=="undefined"&&(!bL||b.event.triggered!==bL.type)?b.event.dispatch.apply(bB.elem,arguments):L};bB.elem=bx}bC=b.trim(bt(bC)).split(" ");for(bI=0;bI=0){bG=bG.slice(0,-1);bw=true}if(bG.indexOf(".")>=0){bx=bG.split(".");bG=bx.shift();bx.sort()}if((!bA||b.event.customEvent[bG])&&!b.event.global[bG]){return}bv=typeof bv==="object"?bv[b.expando]?bv:new b.Event(bG,bv):new b.Event(bG);bv.type=bG;bv.isTrigger=true;bv.exclusive=bw;bv.namespace=bx.join(".");bv.namespace_re=bv.namespace?new RegExp("(^|\\.)"+bx.join("\\.(?:.*\\.)?")+"(\\.|$)"):null;by=bG.indexOf(":")<0?"on"+bG:"";if(!bA){e=b.cache;for(bC in e){if(e[bC].events&&e[bC].events[bG]){b.event.trigger(bv,bD,e[bC].handle.elem,true)}}return}bv.result=L;if(!bv.target){bv.target=bA}bD=bD!=null?b.makeArray(bD):[];bD.unshift(bv);bF=b.event.special[bG]||{};if(bF.trigger&&bF.trigger.apply(bA,bD)===false){return}bB=[[bA,bF.bindType||bG]];if(!bJ&&!bF.noBubble&&!b.isWindow(bA)){bI=bF.delegateType||bG;bH=T.test(bI+bG)?bA:bA.parentNode;bz=null;for(;bH;bH=bH.parentNode){bB.push([bH,bI]);bz=bH}if(bz&&bz===bA.ownerDocument){bB.push([bz.defaultView||bz.parentWindow||bb,bI])}}for(bC=0;bCbA){bH.push({elem:this,matches:bz.slice(bA)})}for(bC=0;bC0?this.on(e,null,bx,bw):this.trigger(e)};if(b.attrFn){b.attrFn[e]=true}if(aO.test(e)){b.event.fixHooks[e]=b.event.keyHooks}if(bf.test(e)){b.event.fixHooks[e]=b.event.mouseHooks}}); +/*! + * Sizzle CSS Selector Engine + * Copyright 2011, The Dojo Foundation + * Released under the MIT, BSD, and GPL Licenses. + * More information: http://sizzlejs.com/ + */ +(function(){var bH=/((?:\((?:\([^()]+\)|[^()]+)+\)|\[(?:\[[^\[\]]*\]|['"][^'"]*['"]|[^\[\]'"]+)+\]|\\.|[^ >+~,(\[\\]+)+|[>+~])(\s*,\s*)?((?:.|\r|\n)*)/g,bC="sizcache"+(Math.random()+"").replace(".",""),bI=0,bL=Object.prototype.toString,bB=false,bA=true,bK=/\\/g,bO=/\r\n/g,bQ=/\W/;[0,0].sort(function(){bA=false;return 0});var by=function(bV,e,bY,bZ){bY=bY||[];e=e||av;var b1=e;if(e.nodeType!==1&&e.nodeType!==9){return[]}if(!bV||typeof bV!=="string"){return bY}var bS,b3,b6,bR,b2,b5,b4,bX,bU=true,bT=by.isXML(e),bW=[],b0=bV;do{bH.exec("");bS=bH.exec(b0);if(bS){b0=bS[3];bW.push(bS[1]);if(bS[2]){bR=bS[3];break}}}while(bS);if(bW.length>1&&bD.exec(bV)){if(bW.length===2&&bE.relative[bW[0]]){b3=bM(bW[0]+bW[1],e,bZ)}else{b3=bE.relative[bW[0]]?[e]:by(bW.shift(),e);while(bW.length){bV=bW.shift();if(bE.relative[bV]){bV+=bW.shift()}b3=bM(bV,b3,bZ)}}}else{if(!bZ&&bW.length>1&&e.nodeType===9&&!bT&&bE.match.ID.test(bW[0])&&!bE.match.ID.test(bW[bW.length-1])){b2=by.find(bW.shift(),e,bT);e=b2.expr?by.filter(b2.expr,b2.set)[0]:b2.set[0]}if(e){b2=bZ?{expr:bW.pop(),set:bF(bZ)}:by.find(bW.pop(),bW.length===1&&(bW[0]==="~"||bW[0]==="+")&&e.parentNode?e.parentNode:e,bT);b3=b2.expr?by.filter(b2.expr,b2.set):b2.set;if(bW.length>0){b6=bF(b3)}else{bU=false}while(bW.length){b5=bW.pop();b4=b5;if(!bE.relative[b5]){b5=""}else{b4=bW.pop()}if(b4==null){b4=e}bE.relative[b5](b6,b4,bT)}}else{b6=bW=[]}}if(!b6){b6=b3}if(!b6){by.error(b5||bV)}if(bL.call(b6)==="[object Array]"){if(!bU){bY.push.apply(bY,b6)}else{if(e&&e.nodeType===1){for(bX=0;b6[bX]!=null;bX++){if(b6[bX]&&(b6[bX]===true||b6[bX].nodeType===1&&by.contains(e,b6[bX]))){bY.push(b3[bX])}}}else{for(bX=0;b6[bX]!=null;bX++){if(b6[bX]&&b6[bX].nodeType===1){bY.push(b3[bX])}}}}}else{bF(b6,bY)}if(bR){by(bR,b1,bY,bZ);by.uniqueSort(bY)}return bY};by.uniqueSort=function(bR){if(bJ){bB=bA;bR.sort(bJ);if(bB){for(var e=1;e0};by.find=function(bX,e,bY){var bW,bS,bU,bT,bV,bR;if(!bX){return[]}for(bS=0,bU=bE.order.length;bS":function(bW,bR){var bV,bU=typeof bR==="string",bS=0,e=bW.length;if(bU&&!bQ.test(bR)){bR=bR.toLowerCase();for(;bS=0)){if(!bS){e.push(bV)}}else{if(bS){bR[bU]=false}}}}return false},ID:function(e){return e[1].replace(bK,"")},TAG:function(bR,e){return bR[1].replace(bK,"").toLowerCase()},CHILD:function(e){if(e[1]==="nth"){if(!e[2]){by.error(e[0])}e[2]=e[2].replace(/^\+|\s*/g,"");var bR=/(-?)(\d*)(?:n([+\-]?\d*))?/.exec(e[2]==="even"&&"2n"||e[2]==="odd"&&"2n+1"||!/\D/.test(e[2])&&"0n+"+e[2]||e[2]);e[2]=(bR[1]+(bR[2]||1))-0;e[3]=bR[3]-0}else{if(e[2]){by.error(e[0])}}e[0]=bI++;return e},ATTR:function(bU,bR,bS,e,bV,bW){var bT=bU[1]=bU[1].replace(bK,"");if(!bW&&bE.attrMap[bT]){bU[1]=bE.attrMap[bT]}bU[4]=(bU[4]||bU[5]||"").replace(bK,"");if(bU[2]==="~="){bU[4]=" "+bU[4]+" "}return bU},PSEUDO:function(bU,bR,bS,e,bV){if(bU[1]==="not"){if((bH.exec(bU[3])||"").length>1||/^\w/.test(bU[3])){bU[3]=by(bU[3],null,null,bR)}else{var bT=by.filter(bU[3],bR,bS,true^bV);if(!bS){e.push.apply(e,bT)}return false}}else{if(bE.match.POS.test(bU[0])||bE.match.CHILD.test(bU[0])){return true}}return bU},POS:function(e){e.unshift(true);return e}},filters:{enabled:function(e){return e.disabled===false&&e.type!=="hidden"},disabled:function(e){return e.disabled===true},checked:function(e){return e.checked===true},selected:function(e){if(e.parentNode){e.parentNode.selectedIndex}return e.selected===true},parent:function(e){return !!e.firstChild},empty:function(e){return !e.firstChild},has:function(bS,bR,e){return !!by(e[3],bS).length},header:function(e){return(/h\d/i).test(e.nodeName)},text:function(bS){var e=bS.getAttribute("type"),bR=bS.type;return bS.nodeName.toLowerCase()==="input"&&"text"===bR&&(e===bR||e===null)},radio:function(e){return e.nodeName.toLowerCase()==="input"&&"radio"===e.type},checkbox:function(e){return e.nodeName.toLowerCase()==="input"&&"checkbox"===e.type},file:function(e){return e.nodeName.toLowerCase()==="input"&&"file"===e.type},password:function(e){return e.nodeName.toLowerCase()==="input"&&"password"===e.type},submit:function(bR){var e=bR.nodeName.toLowerCase();return(e==="input"||e==="button")&&"submit"===bR.type},image:function(e){return e.nodeName.toLowerCase()==="input"&&"image"===e.type},reset:function(bR){var e=bR.nodeName.toLowerCase();return(e==="input"||e==="button")&&"reset"===bR.type},button:function(bR){var e=bR.nodeName.toLowerCase();return e==="input"&&"button"===bR.type||e==="button"},input:function(e){return(/input|select|textarea|button/i).test(e.nodeName)},focus:function(e){return e===e.ownerDocument.activeElement}},setFilters:{first:function(bR,e){return e===0},last:function(bS,bR,e,bT){return bR===bT.length-1},even:function(bR,e){return e%2===0},odd:function(bR,e){return e%2===1},lt:function(bS,bR,e){return bRe[3]-0},nth:function(bS,bR,e){return e[3]-0===bR},eq:function(bS,bR,e){return e[3]-0===bR}},filter:{PSEUDO:function(bS,bX,bW,bY){var e=bX[1],bR=bE.filters[e];if(bR){return bR(bS,bW,bX,bY)}else{if(e==="contains"){return(bS.textContent||bS.innerText||bw([bS])||"").indexOf(bX[3])>=0}else{if(e==="not"){var bT=bX[3];for(var bV=0,bU=bT.length;bV=0)}}},ID:function(bR,e){return bR.nodeType===1&&bR.getAttribute("id")===e},TAG:function(bR,e){return(e==="*"&&bR.nodeType===1)||!!bR.nodeName&&bR.nodeName.toLowerCase()===e},CLASS:function(bR,e){return(" "+(bR.className||bR.getAttribute("class"))+" ").indexOf(e)>-1},ATTR:function(bV,bT){var bS=bT[1],e=by.attr?by.attr(bV,bS):bE.attrHandle[bS]?bE.attrHandle[bS](bV):bV[bS]!=null?bV[bS]:bV.getAttribute(bS),bW=e+"",bU=bT[2],bR=bT[4];return e==null?bU==="!=":!bU&&by.attr?e!=null:bU==="="?bW===bR:bU==="*="?bW.indexOf(bR)>=0:bU==="~="?(" "+bW+" ").indexOf(bR)>=0:!bR?bW&&e!==false:bU==="!="?bW!==bR:bU==="^="?bW.indexOf(bR)===0:bU==="$="?bW.substr(bW.length-bR.length)===bR:bU==="|="?bW===bR||bW.substr(0,bR.length+1)===bR+"-":false},POS:function(bU,bR,bS,bV){var e=bR[2],bT=bE.setFilters[e];if(bT){return bT(bU,bS,bR,bV)}}}};var bD=bE.match.POS,bx=function(bR,e){return"\\"+(e-0+1)};for(var bz in bE.match){bE.match[bz]=new RegExp(bE.match[bz].source+(/(?![^\[]*\])(?![^\(]*\))/.source));bE.leftMatch[bz]=new RegExp(/(^(?:.|\r|\n)*?)/.source+bE.match[bz].source.replace(/\\(\d+)/g,bx))}var bF=function(bR,e){bR=Array.prototype.slice.call(bR,0);if(e){e.push.apply(e,bR);return e}return bR};try{Array.prototype.slice.call(av.documentElement.childNodes,0)[0].nodeType}catch(bP){bF=function(bU,bT){var bS=0,bR=bT||[];if(bL.call(bU)==="[object Array]"){Array.prototype.push.apply(bR,bU)}else{if(typeof bU.length==="number"){for(var e=bU.length;bS";e.insertBefore(bR,e.firstChild);if(av.getElementById(bS)){bE.find.ID=function(bU,bV,bW){if(typeof bV.getElementById!=="undefined"&&!bW){var bT=bV.getElementById(bU[1]);return bT?bT.id===bU[1]||typeof bT.getAttributeNode!=="undefined"&&bT.getAttributeNode("id").nodeValue===bU[1]?[bT]:L:[]}};bE.filter.ID=function(bV,bT){var bU=typeof bV.getAttributeNode!=="undefined"&&bV.getAttributeNode("id");return bV.nodeType===1&&bU&&bU.nodeValue===bT}}e.removeChild(bR);e=bR=null})();(function(){var e=av.createElement("div");e.appendChild(av.createComment(""));if(e.getElementsByTagName("*").length>0){bE.find.TAG=function(bR,bV){var bU=bV.getElementsByTagName(bR[1]);if(bR[1]==="*"){var bT=[];for(var bS=0;bU[bS];bS++){if(bU[bS].nodeType===1){bT.push(bU[bS])}}bU=bT}return bU}}e.innerHTML="";if(e.firstChild&&typeof e.firstChild.getAttribute!=="undefined"&&e.firstChild.getAttribute("href")!=="#"){bE.attrHandle.href=function(bR){return bR.getAttribute("href",2)}}e=null})();if(av.querySelectorAll){(function(){var e=by,bT=av.createElement("div"),bS="__sizzle__";bT.innerHTML="

";if(bT.querySelectorAll&&bT.querySelectorAll(".TEST").length===0){return}by=function(b4,bV,bZ,b3){bV=bV||av;if(!b3&&!by.isXML(bV)){var b2=/^(\w+$)|^\.([\w\-]+$)|^#([\w\-]+$)/.exec(b4);if(b2&&(bV.nodeType===1||bV.nodeType===9)){if(b2[1]){return bF(bV.getElementsByTagName(b4),bZ)}else{if(b2[2]&&bE.find.CLASS&&bV.getElementsByClassName){return bF(bV.getElementsByClassName(b2[2]),bZ)}}}if(bV.nodeType===9){if(b4==="body"&&bV.body){return bF([bV.body],bZ)}else{if(b2&&b2[3]){var bY=bV.getElementById(b2[3]);if(bY&&bY.parentNode){if(bY.id===b2[3]){return bF([bY],bZ)}}else{return bF([],bZ)}}}try{return bF(bV.querySelectorAll(b4),bZ)}catch(b0){}}else{if(bV.nodeType===1&&bV.nodeName.toLowerCase()!=="object"){var bW=bV,bX=bV.getAttribute("id"),bU=bX||bS,b6=bV.parentNode,b5=/^\s*[+~]/.test(b4);if(!bX){bV.setAttribute("id",bU)}else{bU=bU.replace(/'/g,"\\$&")}if(b5&&b6){bV=bV.parentNode}try{if(!b5||b6){return bF(bV.querySelectorAll("[id='"+bU+"'] "+b4),bZ)}}catch(b1){}finally{if(!bX){bW.removeAttribute("id")}}}}}return e(b4,bV,bZ,b3)};for(var bR in e){by[bR]=e[bR]}bT=null})()}(function(){var e=av.documentElement,bS=e.matchesSelector||e.mozMatchesSelector||e.webkitMatchesSelector||e.msMatchesSelector;if(bS){var bU=!bS.call(av.createElement("div"),"div"),bR=false;try{bS.call(av.documentElement,"[test!='']:sizzle")}catch(bT){bR=true}by.matchesSelector=function(bW,bY){bY=bY.replace(/\=\s*([^'"\]]*)\s*\]/g,"='$1']");if(!by.isXML(bW)){try{if(bR||!bE.match.PSEUDO.test(bY)&&!/!=/.test(bY)){var bV=bS.call(bW,bY);if(bV||!bU||bW.document&&bW.document.nodeType!==11){return bV}}}catch(bX){}}return by(bY,null,null,[bW]).length>0}}})();(function(){var e=av.createElement("div");e.innerHTML="
";if(!e.getElementsByClassName||e.getElementsByClassName("e").length===0){return}e.lastChild.className="e";if(e.getElementsByClassName("e").length===1){return}bE.order.splice(1,0,"CLASS");bE.find.CLASS=function(bR,bS,bT){if(typeof bS.getElementsByClassName!=="undefined"&&!bT){return bS.getElementsByClassName(bR[1])}};e=null})();function bv(bR,bW,bV,bZ,bX,bY){for(var bT=0,bS=bZ.length;bT0){bU=e;break}}}e=e[bR]}bZ[bT]=bU}}}if(av.documentElement.contains){by.contains=function(bR,e){return bR!==e&&(bR.contains?bR.contains(e):true)}}else{if(av.documentElement.compareDocumentPosition){by.contains=function(bR,e){return !!(bR.compareDocumentPosition(e)&16)}}else{by.contains=function(){return false}}}by.isXML=function(e){var bR=(e?e.ownerDocument||e:0).documentElement;return bR?bR.nodeName!=="HTML":false};var bM=function(bS,e,bW){var bV,bX=[],bU="",bY=e.nodeType?[e]:e;while((bV=bE.match.PSEUDO.exec(bS))){bU+=bV[0];bS=bS.replace(bE.match.PSEUDO,"")}bS=bE.relative[bS]?bS+"*":bS;for(var bT=0,bR=bY.length;bT0){for(bB=bA;bB=0:b.filter(e,this).length>0:this.filter(e).length>0)},closest:function(by,bx){var bv=[],bw,e,bz=this[0];if(b.isArray(by)){var bB=1;while(bz&&bz.ownerDocument&&bz!==bx){for(bw=0;bw-1:b.find.matchesSelector(bz,by)){bv.push(bz);break}else{bz=bz.parentNode;if(!bz||!bz.ownerDocument||bz===bx||bz.nodeType===11){break}}}}bv=bv.length>1?b.unique(bv):bv;return this.pushStack(bv,"closest",by)},index:function(e){if(!e){return(this[0]&&this[0].parentNode)?this.prevAll().length:-1}if(typeof e==="string"){return b.inArray(this[0],b(e))}return b.inArray(e.jquery?e[0]:e,this)},add:function(e,bv){var bx=typeof e==="string"?b(e,bv):b.makeArray(e&&e.nodeType?[e]:e),bw=b.merge(this.get(),bx);return this.pushStack(C(bx[0])||C(bw[0])?bw:b.unique(bw))},andSelf:function(){return this.add(this.prevObject)}});function C(e){return !e||!e.parentNode||e.parentNode.nodeType===11}b.each({parent:function(bv){var e=bv.parentNode;return e&&e.nodeType!==11?e:null},parents:function(e){return b.dir(e,"parentNode")},parentsUntil:function(bv,e,bw){return b.dir(bv,"parentNode",bw)},next:function(e){return b.nth(e,2,"nextSibling")},prev:function(e){return b.nth(e,2,"previousSibling")},nextAll:function(e){return b.dir(e,"nextSibling")},prevAll:function(e){return b.dir(e,"previousSibling")},nextUntil:function(bv,e,bw){return b.dir(bv,"nextSibling",bw)},prevUntil:function(bv,e,bw){return b.dir(bv,"previousSibling",bw)},siblings:function(e){return b.sibling(e.parentNode.firstChild,e)},children:function(e){return b.sibling(e.firstChild)},contents:function(e){return b.nodeName(e,"iframe")?e.contentDocument||e.contentWindow.document:b.makeArray(e.childNodes)}},function(e,bv){b.fn[e]=function(by,bw){var bx=b.map(this,bv,by);if(!ab.test(e)){bw=by}if(bw&&typeof bw==="string"){bx=b.filter(bw,bx)}bx=this.length>1&&!ay[e]?b.unique(bx):bx;if((this.length>1||a9.test(bw))&&aq.test(e)){bx=bx.reverse()}return this.pushStack(bx,e,P.call(arguments).join(","))}});b.extend({filter:function(bw,e,bv){if(bv){bw=":not("+bw+")"}return e.length===1?b.find.matchesSelector(e[0],bw)?[e[0]]:[]:b.find.matches(bw,e)},dir:function(bw,bv,by){var e=[],bx=bw[bv];while(bx&&bx.nodeType!==9&&(by===L||bx.nodeType!==1||!b(bx).is(by))){if(bx.nodeType===1){e.push(bx)}bx=bx[bv]}return e},nth:function(by,e,bw,bx){e=e||1;var bv=0;for(;by;by=by[bw]){if(by.nodeType===1&&++bv===e){break}}return by},sibling:function(bw,bv){var e=[];for(;bw;bw=bw.nextSibling){if(bw.nodeType===1&&bw!==bv){e.push(bw)}}return e}});function aG(bx,bw,e){bw=bw||0;if(b.isFunction(bw)){return b.grep(bx,function(bz,by){var bA=!!bw.call(bz,by,bz);return bA===e})}else{if(bw.nodeType){return b.grep(bx,function(bz,by){return(bz===bw)===e})}else{if(typeof bw==="string"){var bv=b.grep(bx,function(by){return by.nodeType===1});if(bp.test(bw)){return b.filter(bw,bv,!e)}else{bw=b.filter(bw,bv)}}}}return b.grep(bx,function(bz,by){return(b.inArray(bz,bw)>=0)===e})}function a(e){var bw=aR.split("|"),bv=e.createDocumentFragment();if(bv.createElement){while(bw.length){bv.createElement(bw.pop())}}return bv}var aR="abbr|article|aside|audio|canvas|datalist|details|figcaption|figure|footer|header|hgroup|mark|meter|nav|output|progress|section|summary|time|video",ag=/ jQuery\d+="(?:\d+|null)"/g,ar=/^\s+/,R=/<(?!area|br|col|embed|hr|img|input|link|meta|param)(([\w:]+)[^>]*)\/>/ig,d=/<([\w:]+)/,w=/",""],legend:[1,"
","
"],thead:[1,"","
"],tr:[2,"","
"],td:[3,"","
"],col:[2,"","
"],area:[1,"",""],_default:[0,"",""]},ac=a(av);ax.optgroup=ax.option;ax.tbody=ax.tfoot=ax.colgroup=ax.caption=ax.thead;ax.th=ax.td;if(!b.support.htmlSerialize){ax._default=[1,"div
","
"]}b.fn.extend({text:function(e){if(b.isFunction(e)){return this.each(function(bw){var bv=b(this);bv.text(e.call(this,bw,bv.text()))})}if(typeof e!=="object"&&e!==L){return this.empty().append((this[0]&&this[0].ownerDocument||av).createTextNode(e))}return b.text(this)},wrapAll:function(e){if(b.isFunction(e)){return this.each(function(bw){b(this).wrapAll(e.call(this,bw))})}if(this[0]){var bv=b(e,this[0].ownerDocument).eq(0).clone(true);if(this[0].parentNode){bv.insertBefore(this[0])}bv.map(function(){var bw=this;while(bw.firstChild&&bw.firstChild.nodeType===1){bw=bw.firstChild}return bw}).append(this)}return this},wrapInner:function(e){if(b.isFunction(e)){return this.each(function(bv){b(this).wrapInner(e.call(this,bv))})}return this.each(function(){var bv=b(this),bw=bv.contents();if(bw.length){bw.wrapAll(e)}else{bv.append(e)}})},wrap:function(e){var bv=b.isFunction(e);return this.each(function(bw){b(this).wrapAll(bv?e.call(this,bw):e)})},unwrap:function(){return this.parent().each(function(){if(!b.nodeName(this,"body")){b(this).replaceWith(this.childNodes)}}).end()},append:function(){return this.domManip(arguments,true,function(e){if(this.nodeType===1){this.appendChild(e)}})},prepend:function(){return this.domManip(arguments,true,function(e){if(this.nodeType===1){this.insertBefore(e,this.firstChild)}})},before:function(){if(this[0]&&this[0].parentNode){return this.domManip(arguments,false,function(bv){this.parentNode.insertBefore(bv,this)})}else{if(arguments.length){var e=b.clean(arguments);e.push.apply(e,this.toArray());return this.pushStack(e,"before",arguments)}}},after:function(){if(this[0]&&this[0].parentNode){return this.domManip(arguments,false,function(bv){this.parentNode.insertBefore(bv,this.nextSibling)})}else{if(arguments.length){var e=this.pushStack(this,"after",arguments);e.push.apply(e,b.clean(arguments));return e}}},remove:function(e,bx){for(var bv=0,bw;(bw=this[bv])!=null;bv++){if(!e||b.filter(e,[bw]).length){if(!bx&&bw.nodeType===1){b.cleanData(bw.getElementsByTagName("*"));b.cleanData([bw])}if(bw.parentNode){bw.parentNode.removeChild(bw)}}}return this},empty:function(){for(var e=0,bv;(bv=this[e])!=null;e++){if(bv.nodeType===1){b.cleanData(bv.getElementsByTagName("*"))}while(bv.firstChild){bv.removeChild(bv.firstChild)}}return this},clone:function(bv,e){bv=bv==null?false:bv;e=e==null?bv:e;return this.map(function(){return b.clone(this,bv,e)})},html:function(bx){if(bx===L){return this[0]&&this[0].nodeType===1?this[0].innerHTML.replace(ag,""):null}else{if(typeof bx==="string"&&!ae.test(bx)&&(b.support.leadingWhitespace||!ar.test(bx))&&!ax[(d.exec(bx)||["",""])[1].toLowerCase()]){bx=bx.replace(R,"<$1>");try{for(var bw=0,bv=this.length;bw1&&bw0?this.clone(true):this).get();b(bC[bA])[bv](by);bz=bz.concat(by)}return this.pushStack(bz,e,bC.selector)}}});function bg(e){if(typeof e.getElementsByTagName!=="undefined"){return e.getElementsByTagName("*")}else{if(typeof e.querySelectorAll!=="undefined"){return e.querySelectorAll("*")}else{return[]}}}function az(e){if(e.type==="checkbox"||e.type==="radio"){e.defaultChecked=e.checked}}function E(e){var bv=(e.nodeName||"").toLowerCase();if(bv==="input"){az(e)}else{if(bv!=="script"&&typeof e.getElementsByTagName!=="undefined"){b.grep(e.getElementsByTagName("input"),az)}}}function al(e){var bv=av.createElement("div");ac.appendChild(bv);bv.innerHTML=e.outerHTML;return bv.firstChild}b.extend({clone:function(by,bA,bw){var e,bv,bx,bz=b.support.html5Clone||!ah.test("<"+by.nodeName)?by.cloneNode(true):al(by);if((!b.support.noCloneEvent||!b.support.noCloneChecked)&&(by.nodeType===1||by.nodeType===11)&&!b.isXMLDoc(by)){ai(by,bz);e=bg(by);bv=bg(bz);for(bx=0;e[bx];++bx){if(bv[bx]){ai(e[bx],bv[bx])}}}if(bA){t(by,bz);if(bw){e=bg(by);bv=bg(bz);for(bx=0;e[bx];++bx){t(e[bx],bv[bx])}}}e=bv=null;return bz},clean:function(bw,by,bH,bA){var bF;by=by||av;if(typeof by.createElement==="undefined"){by=by.ownerDocument||by[0]&&by[0].ownerDocument||av}var bI=[],bB;for(var bE=0,bz;(bz=bw[bE])!=null;bE++){if(typeof bz==="number"){bz+=""}if(!bz){continue}if(typeof bz==="string"){if(!W.test(bz)){bz=by.createTextNode(bz)}else{bz=bz.replace(R,"<$1>");var bK=(d.exec(bz)||["",""])[1].toLowerCase(),bx=ax[bK]||ax._default,bD=bx[0],bv=by.createElement("div");if(by===av){ac.appendChild(bv)}else{a(by).appendChild(bv)}bv.innerHTML=bx[1]+bz+bx[2];while(bD--){bv=bv.lastChild}if(!b.support.tbody){var e=w.test(bz),bC=bK==="table"&&!e?bv.firstChild&&bv.firstChild.childNodes:bx[1]===""&&!e?bv.childNodes:[];for(bB=bC.length-1;bB>=0;--bB){if(b.nodeName(bC[bB],"tbody")&&!bC[bB].childNodes.length){bC[bB].parentNode.removeChild(bC[bB])}}}if(!b.support.leadingWhitespace&&ar.test(bz)){bv.insertBefore(by.createTextNode(ar.exec(bz)[0]),bv.firstChild)}bz=bv.childNodes}}var bG;if(!b.support.appendChecked){if(bz[0]&&typeof(bG=bz.length)==="number"){for(bB=0;bB=0){return bx+"px"}}else{return bx}}}});if(!b.support.opacity){b.cssHooks.opacity={get:function(bv,e){return au.test((e&&bv.currentStyle?bv.currentStyle.filter:bv.style.filter)||"")?(parseFloat(RegExp.$1)/100)+"":e?"1":""},set:function(by,bz){var bx=by.style,bv=by.currentStyle,e=b.isNumeric(bz)?"alpha(opacity="+bz*100+")":"",bw=bv&&bv.filter||bx.filter||"";bx.zoom=1;if(bz>=1&&b.trim(bw.replace(ak,""))===""){bx.removeAttribute("filter");if(bv&&!bv.filter){return}}bx.filter=ak.test(bw)?bw.replace(ak,e):bw+" "+e}}}b(function(){if(!b.support.reliableMarginRight){b.cssHooks.marginRight={get:function(bw,bv){var e;b.swap(bw,{display:"inline-block"},function(){if(bv){e=Z(bw,"margin-right","marginRight")}else{e=bw.style.marginRight}});return e}}}});if(av.defaultView&&av.defaultView.getComputedStyle){aI=function(by,bw){var bv,bx,e;bw=bw.replace(z,"-$1").toLowerCase();if((bx=by.ownerDocument.defaultView)&&(e=bx.getComputedStyle(by,null))){bv=e.getPropertyValue(bw);if(bv===""&&!b.contains(by.ownerDocument.documentElement,by)){bv=b.style(by,bw)}}return bv}}if(av.documentElement.currentStyle){aX=function(bz,bw){var bA,e,by,bv=bz.currentStyle&&bz.currentStyle[bw],bx=bz.style;if(bv===null&&bx&&(by=bx[bw])){bv=by}if(!bc.test(bv)&&bn.test(bv)){bA=bx.left;e=bz.runtimeStyle&&bz.runtimeStyle.left;if(e){bz.runtimeStyle.left=bz.currentStyle.left}bx.left=bw==="fontSize"?"1em":(bv||0);bv=bx.pixelLeft+"px";bx.left=bA;if(e){bz.runtimeStyle.left=e}}return bv===""?"auto":bv}}Z=aI||aX;function p(by,bw,bv){var bA=bw==="width"?by.offsetWidth:by.offsetHeight,bz=bw==="width"?an:a1,bx=0,e=bz.length;if(bA>0){if(bv!=="border"){for(;bx)<[^<]*)*<\/script>/gi,q=/^(?:select|textarea)/i,h=/\s+/,br=/([?&])_=[^&]*/,K=/^([\w\+\.\-]+:)(?:\/\/([^\/?#:]*)(?::(\d+))?)?/,A=b.fn.load,aa={},r={},aE,s,aV=["*/"]+["*"];try{aE=bl.href}catch(aw){aE=av.createElement("a");aE.href="";aE=aE.href}s=K.exec(aE.toLowerCase())||[];function f(e){return function(by,bA){if(typeof by!=="string"){bA=by;by="*"}if(b.isFunction(bA)){var bx=by.toLowerCase().split(h),bw=0,bz=bx.length,bv,bB,bC;for(;bw=0){var e=bw.slice(by,bw.length);bw=bw.slice(0,by)}var bx="GET";if(bz){if(b.isFunction(bz)){bA=bz;bz=L}else{if(typeof bz==="object"){bz=b.param(bz,b.ajaxSettings.traditional);bx="POST"}}}var bv=this;b.ajax({url:bw,type:bx,dataType:"html",data:bz,complete:function(bC,bB,bD){bD=bC.responseText;if(bC.isResolved()){bC.done(function(bE){bD=bE});bv.html(e?b("
").append(bD.replace(a6,"")).find(e):bD)}if(bA){bv.each(bA,[bD,bB,bC])}}});return this},serialize:function(){return b.param(this.serializeArray())},serializeArray:function(){return this.map(function(){return this.elements?b.makeArray(this.elements):this}).filter(function(){return this.name&&!this.disabled&&(this.checked||q.test(this.nodeName)||aZ.test(this.type))}).map(function(e,bv){var bw=b(this).val();return bw==null?null:b.isArray(bw)?b.map(bw,function(by,bx){return{name:bv.name,value:by.replace(bs,"\r\n")}}):{name:bv.name,value:bw.replace(bs,"\r\n")}}).get()}});b.each("ajaxStart ajaxStop ajaxComplete ajaxError ajaxSuccess ajaxSend".split(" "),function(e,bv){b.fn[bv]=function(bw){return this.on(bv,bw)}});b.each(["get","post"],function(e,bv){b[bv]=function(bw,by,bz,bx){if(b.isFunction(by)){bx=bx||bz;bz=by;by=L}return b.ajax({type:bv,url:bw,data:by,success:bz,dataType:bx})}});b.extend({getScript:function(e,bv){return b.get(e,L,bv,"script")},getJSON:function(e,bv,bw){return b.get(e,bv,bw,"json")},ajaxSetup:function(bv,e){if(e){am(bv,b.ajaxSettings)}else{e=bv;bv=b.ajaxSettings}am(bv,e);return bv},ajaxSettings:{url:aE,isLocal:aM.test(s[1]),global:true,type:"GET",contentType:"application/x-www-form-urlencoded",processData:true,async:true,accepts:{xml:"application/xml, text/xml",html:"text/html",text:"text/plain",json:"application/json, text/javascript","*":aV},contents:{xml:/xml/,html:/html/,json:/json/},responseFields:{xml:"responseXML",text:"responseText"},converters:{"* text":bb.String,"text html":true,"text json":b.parseJSON,"text xml":b.parseXML},flatOptions:{context:true,url:true}},ajaxPrefilter:f(aa),ajaxTransport:f(r),ajax:function(bz,bx){if(typeof bz==="object"){bx=bz;bz=L}bx=bx||{};var bD=b.ajaxSetup({},bx),bS=bD.context||bD,bG=bS!==bD&&(bS.nodeType||bS instanceof b)?b(bS):b.event,bR=b.Deferred(),bN=b.Callbacks("once memory"),bB=bD.statusCode||{},bC,bH={},bO={},bQ,by,bL,bE,bI,bA=0,bw,bK,bJ={readyState:0,setRequestHeader:function(bT,bU){if(!bA){var e=bT.toLowerCase();bT=bO[e]=bO[e]||bT;bH[bT]=bU}return this},getAllResponseHeaders:function(){return bA===2?bQ:null},getResponseHeader:function(bT){var e;if(bA===2){if(!by){by={};while((e=aD.exec(bQ))){by[e[1].toLowerCase()]=e[2]}}e=by[bT.toLowerCase()]}return e===L?null:e},overrideMimeType:function(e){if(!bA){bD.mimeType=e}return this},abort:function(e){e=e||"abort";if(bL){bL.abort(e)}bF(0,e);return this}};function bF(bZ,bU,b0,bW){if(bA===2){return}bA=2;if(bE){clearTimeout(bE)}bL=L;bQ=bW||"";bJ.readyState=bZ>0?4:0;var bT,b4,b3,bX=bU,bY=b0?bj(bD,bJ,b0):L,bV,b2;if(bZ>=200&&bZ<300||bZ===304){if(bD.ifModified){if((bV=bJ.getResponseHeader("Last-Modified"))){b.lastModified[bC]=bV}if((b2=bJ.getResponseHeader("Etag"))){b.etag[bC]=b2}}if(bZ===304){bX="notmodified";bT=true}else{try{b4=G(bD,bY);bX="success";bT=true}catch(b1){bX="parsererror";b3=b1}}}else{b3=bX;if(!bX||bZ){bX="error";if(bZ<0){bZ=0}}}bJ.status=bZ;bJ.statusText=""+(bU||bX);if(bT){bR.resolveWith(bS,[b4,bX,bJ])}else{bR.rejectWith(bS,[bJ,bX,b3])}bJ.statusCode(bB);bB=L;if(bw){bG.trigger("ajax"+(bT?"Success":"Error"),[bJ,bD,bT?b4:b3])}bN.fireWith(bS,[bJ,bX]);if(bw){bG.trigger("ajaxComplete",[bJ,bD]);if(!(--b.active)){b.event.trigger("ajaxStop")}}}bR.promise(bJ);bJ.success=bJ.done;bJ.error=bJ.fail;bJ.complete=bN.add;bJ.statusCode=function(bT){if(bT){var e;if(bA<2){for(e in bT){bB[e]=[bB[e],bT[e]]}}else{e=bT[bJ.status];bJ.then(e,e)}}return this};bD.url=((bz||bD.url)+"").replace(bq,"").replace(c,s[1]+"//");bD.dataTypes=b.trim(bD.dataType||"*").toLowerCase().split(h);if(bD.crossDomain==null){bI=K.exec(bD.url.toLowerCase());bD.crossDomain=!!(bI&&(bI[1]!=s[1]||bI[2]!=s[2]||(bI[3]||(bI[1]==="http:"?80:443))!=(s[3]||(s[1]==="http:"?80:443))))}if(bD.data&&bD.processData&&typeof bD.data!=="string"){bD.data=b.param(bD.data,bD.traditional)}aW(aa,bD,bx,bJ);if(bA===2){return false}bw=bD.global;bD.type=bD.type.toUpperCase();bD.hasContent=!aQ.test(bD.type);if(bw&&b.active++===0){b.event.trigger("ajaxStart")}if(!bD.hasContent){if(bD.data){bD.url+=(M.test(bD.url)?"&":"?")+bD.data;delete bD.data}bC=bD.url;if(bD.cache===false){var bv=b.now(),bP=bD.url.replace(br,"$1_="+bv);bD.url=bP+((bP===bD.url)?(M.test(bD.url)?"&":"?")+"_="+bv:"")}}if(bD.data&&bD.hasContent&&bD.contentType!==false||bx.contentType){bJ.setRequestHeader("Content-Type",bD.contentType)}if(bD.ifModified){bC=bC||bD.url;if(b.lastModified[bC]){bJ.setRequestHeader("If-Modified-Since",b.lastModified[bC])}if(b.etag[bC]){bJ.setRequestHeader("If-None-Match",b.etag[bC])}}bJ.setRequestHeader("Accept",bD.dataTypes[0]&&bD.accepts[bD.dataTypes[0]]?bD.accepts[bD.dataTypes[0]]+(bD.dataTypes[0]!=="*"?", "+aV+"; q=0.01":""):bD.accepts["*"]);for(bK in bD.headers){bJ.setRequestHeader(bK,bD.headers[bK])}if(bD.beforeSend&&(bD.beforeSend.call(bS,bJ,bD)===false||bA===2)){bJ.abort();return false}for(bK in {success:1,error:1,complete:1}){bJ[bK](bD[bK])}bL=aW(r,bD,bx,bJ);if(!bL){bF(-1,"No Transport")}else{bJ.readyState=1;if(bw){bG.trigger("ajaxSend",[bJ,bD])}if(bD.async&&bD.timeout>0){bE=setTimeout(function(){bJ.abort("timeout")},bD.timeout)}try{bA=1;bL.send(bH,bF)}catch(bM){if(bA<2){bF(-1,bM)}else{throw bM}}}return bJ},param:function(e,bw){var bv=[],by=function(bz,bA){bA=b.isFunction(bA)?bA():bA;bv[bv.length]=encodeURIComponent(bz)+"="+encodeURIComponent(bA)};if(bw===L){bw=b.ajaxSettings.traditional}if(b.isArray(e)||(e.jquery&&!b.isPlainObject(e))){b.each(e,function(){by(this.name,this.value)})}else{for(var bx in e){v(bx,e[bx],bw,by)}}return bv.join("&").replace(k,"+")}});function v(bw,by,bv,bx){if(b.isArray(by)){b.each(by,function(bA,bz){if(bv||ap.test(bw)){bx(bw,bz)}else{v(bw+"["+(typeof bz==="object"||b.isArray(bz)?bA:"")+"]",bz,bv,bx)}})}else{if(!bv&&by!=null&&typeof by==="object"){for(var e in by){v(bw+"["+e+"]",by[e],bv,bx)}}else{bx(bw,by)}}}b.extend({active:0,lastModified:{},etag:{}});function bj(bD,bC,bz){var bv=bD.contents,bB=bD.dataTypes,bw=bD.responseFields,by,bA,bx,e;for(bA in bw){if(bA in bz){bC[bw[bA]]=bz[bA]}}while(bB[0]==="*"){bB.shift();if(by===L){by=bD.mimeType||bC.getResponseHeader("content-type")}}if(by){for(bA in bv){if(bv[bA]&&bv[bA].test(by)){bB.unshift(bA);break}}}if(bB[0] in bz){bx=bB[0]}else{for(bA in bz){if(!bB[0]||bD.converters[bA+" "+bB[0]]){bx=bA;break}if(!e){e=bA}}bx=bx||e}if(bx){if(bx!==bB[0]){bB.unshift(bx)}return bz[bx]}}function G(bH,bz){if(bH.dataFilter){bz=bH.dataFilter(bz,bH.dataType)}var bD=bH.dataTypes,bG={},bA,bE,bw=bD.length,bB,bC=bD[0],bx,by,bF,bv,e;for(bA=1;bA=bw.duration+this.startTime){this.now=this.end;this.pos=this.state=1;this.update();bw.animatedProperties[this.prop]=true;for(bA in bw.animatedProperties){if(bw.animatedProperties[bA]!==true){e=false}}if(e){if(bw.overflow!=null&&!b.support.shrinkWrapBlocks){b.each(["","X","Y"],function(bC,bD){bz.style["overflow"+bD]=bw.overflow[bC]})}if(bw.hide){b(bz).hide()}if(bw.hide||bw.show){for(bA in bw.animatedProperties){b.style(bz,bA,bw.orig[bA]);b.removeData(bz,"fxshow"+bA,true);b.removeData(bz,"toggle"+bA,true)}}bv=bw.complete;if(bv){bw.complete=false;bv.call(bz)}}return false}else{if(bw.duration==Infinity){this.now=bx}else{bB=bx-this.startTime;this.state=bB/bw.duration;this.pos=b.easing[bw.animatedProperties[this.prop]](this.state,bB,0,1,bw.duration);this.now=this.start+((this.end-this.start)*this.pos)}this.update()}return true}};b.extend(b.fx,{tick:function(){var bw,bv=b.timers,e=0;for(;e").appendTo(e),bw=bv.css("display");bv.remove();if(bw==="none"||bw===""){if(!a8){a8=av.createElement("iframe");a8.frameBorder=a8.width=a8.height=0}e.appendChild(a8);if(!m||!a8.createElement){m=(a8.contentWindow||a8.contentDocument).document;m.write((av.compatMode==="CSS1Compat"?"":"")+"");m.close()}bv=m.createElement(bx);m.body.appendChild(bv);bw=b.css(bv,"display");e.removeChild(a8)}Q[bx]=bw}return Q[bx]}var V=/^t(?:able|d|h)$/i,ad=/^(?:body|html)$/i;if("getBoundingClientRect" in av.documentElement){b.fn.offset=function(bI){var by=this[0],bB;if(bI){return this.each(function(e){b.offset.setOffset(this,bI,e)})}if(!by||!by.ownerDocument){return null}if(by===by.ownerDocument.body){return b.offset.bodyOffset(by)}try{bB=by.getBoundingClientRect()}catch(bF){}var bH=by.ownerDocument,bw=bH.documentElement;if(!bB||!b.contains(bw,by)){return bB?{top:bB.top,left:bB.left}:{top:0,left:0}}var bC=bH.body,bD=aK(bH),bA=bw.clientTop||bC.clientTop||0,bE=bw.clientLeft||bC.clientLeft||0,bv=bD.pageYOffset||b.support.boxModel&&bw.scrollTop||bC.scrollTop,bz=bD.pageXOffset||b.support.boxModel&&bw.scrollLeft||bC.scrollLeft,bG=bB.top+bv-bA,bx=bB.left+bz-bE;return{top:bG,left:bx}}}else{b.fn.offset=function(bF){var bz=this[0];if(bF){return this.each(function(bG){b.offset.setOffset(this,bF,bG)})}if(!bz||!bz.ownerDocument){return null}if(bz===bz.ownerDocument.body){return b.offset.bodyOffset(bz)}var bC,bw=bz.offsetParent,bv=bz,bE=bz.ownerDocument,bx=bE.documentElement,bA=bE.body,bB=bE.defaultView,e=bB?bB.getComputedStyle(bz,null):bz.currentStyle,bD=bz.offsetTop,by=bz.offsetLeft;while((bz=bz.parentNode)&&bz!==bA&&bz!==bx){if(b.support.fixedPosition&&e.position==="fixed"){break}bC=bB?bB.getComputedStyle(bz,null):bz.currentStyle;bD-=bz.scrollTop;by-=bz.scrollLeft;if(bz===bw){bD+=bz.offsetTop;by+=bz.offsetLeft;if(b.support.doesNotAddBorder&&!(b.support.doesAddBorderForTableAndCells&&V.test(bz.nodeName))){bD+=parseFloat(bC.borderTopWidth)||0;by+=parseFloat(bC.borderLeftWidth)||0}bv=bw;bw=bz.offsetParent}if(b.support.subtractsBorderForOverflowNotVisible&&bC.overflow!=="visible"){bD+=parseFloat(bC.borderTopWidth)||0;by+=parseFloat(bC.borderLeftWidth)||0}e=bC}if(e.position==="relative"||e.position==="static"){bD+=bA.offsetTop;by+=bA.offsetLeft}if(b.support.fixedPosition&&e.position==="fixed"){bD+=Math.max(bx.scrollTop,bA.scrollTop);by+=Math.max(bx.scrollLeft,bA.scrollLeft)}return{top:bD,left:by}}}b.offset={bodyOffset:function(e){var bw=e.offsetTop,bv=e.offsetLeft;if(b.support.doesNotIncludeMarginInBodyOffset){bw+=parseFloat(b.css(e,"marginTop"))||0;bv+=parseFloat(b.css(e,"marginLeft"))||0}return{top:bw,left:bv}},setOffset:function(bx,bG,bA){var bB=b.css(bx,"position");if(bB==="static"){bx.style.position="relative"}var bz=b(bx),bv=bz.offset(),e=b.css(bx,"top"),bE=b.css(bx,"left"),bF=(bB==="absolute"||bB==="fixed")&&b.inArray("auto",[e,bE])>-1,bD={},bC={},bw,by;if(bF){bC=bz.position();bw=bC.top;by=bC.left}else{bw=parseFloat(e)||0;by=parseFloat(bE)||0}if(b.isFunction(bG)){bG=bG.call(bx,bA,bv)}if(bG.top!=null){bD.top=(bG.top-bv.top)+bw}if(bG.left!=null){bD.left=(bG.left-bv.left)+by}if("using" in bG){bG.using.call(bx,bD)}else{bz.css(bD)}}};b.fn.extend({position:function(){if(!this[0]){return null}var bw=this[0],bv=this.offsetParent(),bx=this.offset(),e=ad.test(bv[0].nodeName)?{top:0,left:0}:bv.offset();bx.top-=parseFloat(b.css(bw,"marginTop"))||0;bx.left-=parseFloat(b.css(bw,"marginLeft"))||0;e.top+=parseFloat(b.css(bv[0],"borderTopWidth"))||0;e.left+=parseFloat(b.css(bv[0],"borderLeftWidth"))||0;return{top:bx.top-e.top,left:bx.left-e.left}},offsetParent:function(){return this.map(function(){var e=this.offsetParent||av.body;while(e&&(!ad.test(e.nodeName)&&b.css(e,"position")==="static")){e=e.offsetParent}return e})}});b.each(["Left","Top"],function(bv,e){var bw="scroll"+e;b.fn[bw]=function(bz){var bx,by;if(bz===L){bx=this[0];if(!bx){return null}by=aK(bx);return by?("pageXOffset" in by)?by[bv?"pageYOffset":"pageXOffset"]:b.support.boxModel&&by.document.documentElement[bw]||by.document.body[bw]:bx[bw]}return this.each(function(){by=aK(this);if(by){by.scrollTo(!bv?bz:b(by).scrollLeft(),bv?bz:b(by).scrollTop())}else{this[bw]=bz}})}});function aK(e){return b.isWindow(e)?e:e.nodeType===9?e.defaultView||e.parentWindow:false}b.each(["Height","Width"],function(bv,e){var bw=e.toLowerCase();b.fn["inner"+e]=function(){var bx=this[0];return bx?bx.style?parseFloat(b.css(bx,bw,"padding")):this[bw]():null};b.fn["outer"+e]=function(by){var bx=this[0];return bx?bx.style?parseFloat(b.css(bx,bw,by?"margin":"border")):this[bw]():null};b.fn[bw]=function(bz){var bA=this[0];if(!bA){return bz==null?null:this}if(b.isFunction(bz)){return this.each(function(bE){var bD=b(this);bD[bw](bz.call(this,bE,bD[bw]()))})}if(b.isWindow(bA)){var bB=bA.document.documentElement["client"+e],bx=bA.document.body;return bA.document.compatMode==="CSS1Compat"&&bB||bx&&bx["client"+e]||bB}else{if(bA.nodeType===9){return Math.max(bA.documentElement["client"+e],bA.body["scroll"+e],bA.documentElement["scroll"+e],bA.body["offset"+e],bA.documentElement["offset"+e])}else{if(bz===L){var bC=b.css(bA,bw),by=parseFloat(bC);return b.isNumeric(by)?by:bC}else{return this.css(bw,typeof bz==="string"?bz:bz+"px")}}}}});bb.jQuery=bb.$=b;if(typeof define==="function"&&define.amd&&define.amd.jQuery){define("jquery",[],function(){return b})}})(window);/*! + * jQuery UI 1.8.18 + * + * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about) + * Dual licensed under the MIT or GPL Version 2 licenses. + * http://jquery.org/license + * + * http://docs.jquery.com/UI + */ +(function(a,d){a.ui=a.ui||{};if(a.ui.version){return}a.extend(a.ui,{version:"1.8.18",keyCode:{ALT:18,BACKSPACE:8,CAPS_LOCK:20,COMMA:188,COMMAND:91,COMMAND_LEFT:91,COMMAND_RIGHT:93,CONTROL:17,DELETE:46,DOWN:40,END:35,ENTER:13,ESCAPE:27,HOME:36,INSERT:45,LEFT:37,MENU:93,NUMPAD_ADD:107,NUMPAD_DECIMAL:110,NUMPAD_DIVIDE:111,NUMPAD_ENTER:108,NUMPAD_MULTIPLY:106,NUMPAD_SUBTRACT:109,PAGE_DOWN:34,PAGE_UP:33,PERIOD:190,RIGHT:39,SHIFT:16,SPACE:32,TAB:9,UP:38,WINDOWS:91}});a.fn.extend({propAttr:a.fn.prop||a.fn.attr,_focus:a.fn.focus,focus:function(e,f){return typeof e==="number"?this.each(function(){var g=this;setTimeout(function(){a(g).focus();if(f){f.call(g)}},e)}):this._focus.apply(this,arguments)},scrollParent:function(){var e;if((a.browser.msie&&(/(static|relative)/).test(this.css("position")))||(/absolute/).test(this.css("position"))){e=this.parents().filter(function(){return(/(relative|absolute|fixed)/).test(a.curCSS(this,"position",1))&&(/(auto|scroll)/).test(a.curCSS(this,"overflow",1)+a.curCSS(this,"overflow-y",1)+a.curCSS(this,"overflow-x",1))}).eq(0)}else{e=this.parents().filter(function(){return(/(auto|scroll)/).test(a.curCSS(this,"overflow",1)+a.curCSS(this,"overflow-y",1)+a.curCSS(this,"overflow-x",1))}).eq(0)}return(/fixed/).test(this.css("position"))||!e.length?a(document):e},zIndex:function(h){if(h!==d){return this.css("zIndex",h)}if(this.length){var f=a(this[0]),e,g;while(f.length&&f[0]!==document){e=f.css("position");if(e==="absolute"||e==="relative"||e==="fixed"){g=parseInt(f.css("zIndex"),10);if(!isNaN(g)&&g!==0){return g}}f=f.parent()}}return 0},disableSelection:function(){return this.bind((a.support.selectstart?"selectstart":"mousedown")+".ui-disableSelection",function(e){e.preventDefault()})},enableSelection:function(){return this.unbind(".ui-disableSelection")}});a.each(["Width","Height"],function(g,e){var f=e==="Width"?["Left","Right"]:["Top","Bottom"],h=e.toLowerCase(),k={innerWidth:a.fn.innerWidth,innerHeight:a.fn.innerHeight,outerWidth:a.fn.outerWidth,outerHeight:a.fn.outerHeight};function j(m,l,i,n){a.each(f,function(){l-=parseFloat(a.curCSS(m,"padding"+this,true))||0;if(i){l-=parseFloat(a.curCSS(m,"border"+this+"Width",true))||0}if(n){l-=parseFloat(a.curCSS(m,"margin"+this,true))||0}});return l}a.fn["inner"+e]=function(i){if(i===d){return k["inner"+e].call(this)}return this.each(function(){a(this).css(h,j(this,i)+"px")})};a.fn["outer"+e]=function(i,l){if(typeof i!=="number"){return k["outer"+e].call(this,i)}return this.each(function(){a(this).css(h,j(this,i,true,l)+"px")})}});function c(g,e){var j=g.nodeName.toLowerCase();if("area"===j){var i=g.parentNode,h=i.name,f;if(!g.href||!h||i.nodeName.toLowerCase()!=="map"){return false}f=a("img[usemap=#"+h+"]")[0];return !!f&&b(f)}return(/input|select|textarea|button|object/.test(j)?!g.disabled:"a"==j?g.href||e:e)&&b(g)}function b(e){return !a(e).parents().andSelf().filter(function(){return a.curCSS(this,"visibility")==="hidden"||a.expr.filters.hidden(this)}).length}a.extend(a.expr[":"],{data:function(g,f,e){return !!a.data(g,e[3])},focusable:function(e){return c(e,!isNaN(a.attr(e,"tabindex")))},tabbable:function(g){var e=a.attr(g,"tabindex"),f=isNaN(e);return(f||e>=0)&&c(g,!f)}});a(function(){var e=document.body,f=e.appendChild(f=document.createElement("div"));f.offsetHeight;a.extend(f.style,{minHeight:"100px",height:"auto",padding:0,borderWidth:0});a.support.minHeight=f.offsetHeight===100;a.support.selectstart="onselectstart" in f;e.removeChild(f).style.display="none"});a.extend(a.ui,{plugin:{add:function(f,g,j){var h=a.ui[f].prototype;for(var e in j){h.plugins[e]=h.plugins[e]||[];h.plugins[e].push([g,j[e]])}},call:function(e,g,f){var j=e.plugins[g];if(!j||!e.element[0].parentNode){return}for(var h=0;h0){return true}h[e]=1;g=(h[e]>0);h[e]=0;return g},isOverAxis:function(f,e,g){return(f>e)&&(f<(e+g))},isOver:function(j,f,i,h,e,g){return a.ui.isOverAxis(j,i,e)&&a.ui.isOverAxis(f,h,g)}})})(jQuery);/*! + * jQuery UI Widget 1.8.18 + * + * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about) + * Dual licensed under the MIT or GPL Version 2 licenses. + * http://jquery.org/license + * + * http://docs.jquery.com/UI/Widget + */ +(function(b,d){if(b.cleanData){var c=b.cleanData;b.cleanData=function(f){for(var g=0,h;(h=f[g])!=null;g++){try{b(h).triggerHandler("remove")}catch(j){}}c(f)}}else{var a=b.fn.remove;b.fn.remove=function(e,f){return this.each(function(){if(!f){if(!e||b.filter(e,[this]).length){b("*",this).add([this]).each(function(){try{b(this).triggerHandler("remove")}catch(g){}})}}return a.call(b(this),e,f)})}}b.widget=function(f,h,e){var g=f.split(".")[0],j;f=f.split(".")[1];j=g+"-"+f;if(!e){e=h;h=b.Widget}b.expr[":"][j]=function(k){return !!b.data(k,f)};b[g]=b[g]||{};b[g][f]=function(k,l){if(arguments.length){this._createWidget(k,l)}};var i=new h();i.options=b.extend(true,{},i.options);b[g][f].prototype=b.extend(true,i,{namespace:g,widgetName:f,widgetEventPrefix:b[g][f].prototype.widgetEventPrefix||f,widgetBaseClass:j},e);b.widget.bridge(f,b[g][f])};b.widget.bridge=function(f,e){b.fn[f]=function(i){var g=typeof i==="string",h=Array.prototype.slice.call(arguments,1),j=this;i=!g&&h.length?b.extend.apply(null,[true,i].concat(h)):i;if(g&&i.charAt(0)==="_"){return j}if(g){this.each(function(){var k=b.data(this,f),l=k&&b.isFunction(k[i])?k[i].apply(k,h):k;if(l!==k&&l!==d){j=l;return false}})}else{this.each(function(){var k=b.data(this,f);if(k){k.option(i||{})._init()}else{b.data(this,f,new e(i,this))}})}return j}};b.Widget=function(e,f){if(arguments.length){this._createWidget(e,f)}};b.Widget.prototype={widgetName:"widget",widgetEventPrefix:"",options:{disabled:false},_createWidget:function(f,g){b.data(g,this.widgetName,this);this.element=b(g);this.options=b.extend(true,{},this.options,this._getCreateOptions(),f);var e=this;this.element.bind("remove."+this.widgetName,function(){e.destroy()});this._create();this._trigger("create");this._init()},_getCreateOptions:function(){return b.metadata&&b.metadata.get(this.element[0])[this.widgetName]},_create:function(){},_init:function(){},destroy:function(){this.element.unbind("."+this.widgetName).removeData(this.widgetName);this.widget().unbind("."+this.widgetName).removeAttr("aria-disabled").removeClass(this.widgetBaseClass+"-disabled ui-state-disabled")},widget:function(){return this.element},option:function(f,g){var e=f;if(arguments.length===0){return b.extend({},this.options)}if(typeof f==="string"){if(g===d){return this.options[f]}e={};e[f]=g}this._setOptions(e);return this},_setOptions:function(f){var e=this;b.each(f,function(g,h){e._setOption(g,h)});return this},_setOption:function(e,f){this.options[e]=f;if(e==="disabled"){this.widget()[f?"addClass":"removeClass"](this.widgetBaseClass+"-disabled ui-state-disabled").attr("aria-disabled",f)}return this},enable:function(){return this._setOption("disabled",false)},disable:function(){return this._setOption("disabled",true)},_trigger:function(e,f,g){var j,i,h=this.options[e];g=g||{};f=b.Event(f);f.type=(e===this.widgetEventPrefix?e:this.widgetEventPrefix+e).toLowerCase();f.target=this.element[0];i=f.originalEvent;if(i){for(j in i){if(!(j in f)){f[j]=i[j]}}}this.element.trigger(f,g);return !(b.isFunction(h)&&h.call(this.element[0],f,g)===false||f.isDefaultPrevented())}}})(jQuery);/*! + * jQuery UI Mouse 1.8.18 + * + * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about) + * Dual licensed under the MIT or GPL Version 2 licenses. + * http://jquery.org/license + * + * http://docs.jquery.com/UI/Mouse + * + * Depends: + * jquery.ui.widget.js + */ +(function(b,c){var a=false;b(document).mouseup(function(d){a=false});b.widget("ui.mouse",{options:{cancel:":input,option",distance:1,delay:0},_mouseInit:function(){var d=this;this.element.bind("mousedown."+this.widgetName,function(e){return d._mouseDown(e)}).bind("click."+this.widgetName,function(e){if(true===b.data(e.target,d.widgetName+".preventClickEvent")){b.removeData(e.target,d.widgetName+".preventClickEvent");e.stopImmediatePropagation();return false}});this.started=false},_mouseDestroy:function(){this.element.unbind("."+this.widgetName)},_mouseDown:function(f){if(a){return}(this._mouseStarted&&this._mouseUp(f));this._mouseDownEvent=f;var e=this,g=(f.which==1),d=(typeof this.options.cancel=="string"&&f.target.nodeName?b(f.target).closest(this.options.cancel).length:false);if(!g||d||!this._mouseCapture(f)){return true}this.mouseDelayMet=!this.options.delay;if(!this.mouseDelayMet){this._mouseDelayTimer=setTimeout(function(){e.mouseDelayMet=true},this.options.delay)}if(this._mouseDistanceMet(f)&&this._mouseDelayMet(f)){this._mouseStarted=(this._mouseStart(f)!==false);if(!this._mouseStarted){f.preventDefault();return true}}if(true===b.data(f.target,this.widgetName+".preventClickEvent")){b.removeData(f.target,this.widgetName+".preventClickEvent")}this._mouseMoveDelegate=function(h){return e._mouseMove(h)};this._mouseUpDelegate=function(h){return e._mouseUp(h)};b(document).bind("mousemove."+this.widgetName,this._mouseMoveDelegate).bind("mouseup."+this.widgetName,this._mouseUpDelegate);f.preventDefault();a=true;return true},_mouseMove:function(d){if(b.browser.msie&&!(document.documentMode>=9)&&!d.button){return this._mouseUp(d)}if(this._mouseStarted){this._mouseDrag(d);return d.preventDefault()}if(this._mouseDistanceMet(d)&&this._mouseDelayMet(d)){this._mouseStarted=(this._mouseStart(this._mouseDownEvent,d)!==false);(this._mouseStarted?this._mouseDrag(d):this._mouseUp(d))}return !this._mouseStarted},_mouseUp:function(d){b(document).unbind("mousemove."+this.widgetName,this._mouseMoveDelegate).unbind("mouseup."+this.widgetName,this._mouseUpDelegate);if(this._mouseStarted){this._mouseStarted=false;if(d.target==this._mouseDownEvent.target){b.data(d.target,this.widgetName+".preventClickEvent",true)}this._mouseStop(d)}return false},_mouseDistanceMet:function(d){return(Math.max(Math.abs(this._mouseDownEvent.pageX-d.pageX),Math.abs(this._mouseDownEvent.pageY-d.pageY))>=this.options.distance)},_mouseDelayMet:function(d){return this.mouseDelayMet},_mouseStart:function(d){},_mouseDrag:function(d){},_mouseStop:function(d){},_mouseCapture:function(d){return true}})})(jQuery);(function(c,d){c.widget("ui.resizable",c.ui.mouse,{widgetEventPrefix:"resize",options:{alsoResize:false,animate:false,animateDuration:"slow",animateEasing:"swing",aspectRatio:false,autoHide:false,containment:false,ghost:false,grid:false,handles:"e,s,se",helper:false,maxHeight:null,maxWidth:null,minHeight:10,minWidth:10,zIndex:1000},_create:function(){var f=this,k=this.options;this.element.addClass("ui-resizable");c.extend(this,{_aspectRatio:!!(k.aspectRatio),aspectRatio:k.aspectRatio,originalElement:this.element,_proportionallyResizeElements:[],_helper:k.helper||k.ghost||k.animate?k.helper||"ui-resizable-helper":null});if(this.element[0].nodeName.match(/canvas|textarea|input|select|button|img/i)){this.element.wrap(c('
').css({position:this.element.css("position"),width:this.element.outerWidth(),height:this.element.outerHeight(),top:this.element.css("top"),left:this.element.css("left")}));this.element=this.element.parent().data("resizable",this.element.data("resizable"));this.elementIsWrapper=true;this.element.css({marginLeft:this.originalElement.css("marginLeft"),marginTop:this.originalElement.css("marginTop"),marginRight:this.originalElement.css("marginRight"),marginBottom:this.originalElement.css("marginBottom")});this.originalElement.css({marginLeft:0,marginTop:0,marginRight:0,marginBottom:0});this.originalResizeStyle=this.originalElement.css("resize");this.originalElement.css("resize","none");this._proportionallyResizeElements.push(this.originalElement.css({position:"static",zoom:1,display:"block"}));this.originalElement.css({margin:this.originalElement.css("margin")});this._proportionallyResize()}this.handles=k.handles||(!c(".ui-resizable-handle",this.element).length?"e,s,se":{n:".ui-resizable-n",e:".ui-resizable-e",s:".ui-resizable-s",w:".ui-resizable-w",se:".ui-resizable-se",sw:".ui-resizable-sw",ne:".ui-resizable-ne",nw:".ui-resizable-nw"});if(this.handles.constructor==String){if(this.handles=="all"){this.handles="n,e,s,w,se,sw,ne,nw"}var l=this.handles.split(",");this.handles={};for(var g=0;g
');if(/sw|se|ne|nw/.test(j)){h.css({zIndex:++k.zIndex})}if("se"==j){h.addClass("ui-icon ui-icon-gripsmall-diagonal-se")}this.handles[j]=".ui-resizable-"+j;this.element.append(h)}}this._renderAxis=function(q){q=q||this.element;for(var n in this.handles){if(this.handles[n].constructor==String){this.handles[n]=c(this.handles[n],this.element).show()}if(this.elementIsWrapper&&this.originalElement[0].nodeName.match(/textarea|input|select|button/i)){var o=c(this.handles[n],this.element),p=0;p=/sw|ne|nw|se|n|s/.test(n)?o.outerHeight():o.outerWidth();var m=["padding",/ne|nw|n/.test(n)?"Top":/se|sw|s/.test(n)?"Bottom":/^e$/.test(n)?"Right":"Left"].join("");q.css(m,p);this._proportionallyResize()}if(!c(this.handles[n]).length){continue}}};this._renderAxis(this.element);this._handles=c(".ui-resizable-handle",this.element).disableSelection();this._handles.mouseover(function(){if(!f.resizing){if(this.className){var i=this.className.match(/ui-resizable-(se|sw|ne|nw|n|e|s|w)/i)}f.axis=i&&i[1]?i[1]:"se"}});if(k.autoHide){this._handles.hide();c(this.element).addClass("ui-resizable-autohide").hover(function(){if(k.disabled){return}c(this).removeClass("ui-resizable-autohide");f._handles.show()},function(){if(k.disabled){return}if(!f.resizing){c(this).addClass("ui-resizable-autohide");f._handles.hide()}})}this._mouseInit()},destroy:function(){this._mouseDestroy();var e=function(g){c(g).removeClass("ui-resizable ui-resizable-disabled ui-resizable-resizing").removeData("resizable").unbind(".resizable").find(".ui-resizable-handle").remove()};if(this.elementIsWrapper){e(this.element);var f=this.element;f.after(this.originalElement.css({position:f.css("position"),width:f.outerWidth(),height:f.outerHeight(),top:f.css("top"),left:f.css("left")})).remove()}this.originalElement.css("resize",this.originalResizeStyle);e(this.originalElement);return this},_mouseCapture:function(f){var g=false;for(var e in this.handles){if(c(this.handles[e])[0]==f.target){g=true}}return !this.options.disabled&&g},_mouseStart:function(g){var j=this.options,f=this.element.position(),e=this.element;this.resizing=true;this.documentScroll={top:c(document).scrollTop(),left:c(document).scrollLeft()};if(e.is(".ui-draggable")||(/absolute/).test(e.css("position"))){e.css({position:"absolute",top:f.top,left:f.left})}this._renderProxy();var k=b(this.helper.css("left")),h=b(this.helper.css("top"));if(j.containment){k+=c(j.containment).scrollLeft()||0;h+=c(j.containment).scrollTop()||0}this.offset=this.helper.offset();this.position={left:k,top:h};this.size=this._helper?{width:e.outerWidth(),height:e.outerHeight()}:{width:e.width(),height:e.height()};this.originalSize=this._helper?{width:e.outerWidth(),height:e.outerHeight()}:{width:e.width(),height:e.height()};this.originalPosition={left:k,top:h};this.sizeDiff={width:e.outerWidth()-e.width(),height:e.outerHeight()-e.height()};this.originalMousePosition={left:g.pageX,top:g.pageY};this.aspectRatio=(typeof j.aspectRatio=="number")?j.aspectRatio:((this.originalSize.width/this.originalSize.height)||1);var i=c(".ui-resizable-"+this.axis).css("cursor");c("body").css("cursor",i=="auto"?this.axis+"-resize":i);e.addClass("ui-resizable-resizing");this._propagate("start",g);return true},_mouseDrag:function(e){var h=this.helper,g=this.options,m={},q=this,j=this.originalMousePosition,n=this.axis;var r=(e.pageX-j.left)||0,p=(e.pageY-j.top)||0;var i=this._change[n];if(!i){return false}var l=i.apply(this,[e,r,p]),k=c.browser.msie&&c.browser.version<7,f=this.sizeDiff;this._updateVirtualBoundaries(e.shiftKey);if(this._aspectRatio||e.shiftKey){l=this._updateRatio(l,e)}l=this._respectSize(l,e);this._propagate("resize",e);h.css({top:this.position.top+"px",left:this.position.left+"px",width:this.size.width+"px",height:this.size.height+"px"});if(!this._helper&&this._proportionallyResizeElements.length){this._proportionallyResize()}this._updateCache(l);this._trigger("resize",e,this.ui());return false},_mouseStop:function(h){this.resizing=false;var i=this.options,m=this;if(this._helper){var g=this._proportionallyResizeElements,e=g.length&&(/textarea/i).test(g[0].nodeName),f=e&&c.ui.hasScroll(g[0],"left")?0:m.sizeDiff.height,k=e?0:m.sizeDiff.width;var n={width:(m.helper.width()-k),height:(m.helper.height()-f)},j=(parseInt(m.element.css("left"),10)+(m.position.left-m.originalPosition.left))||null,l=(parseInt(m.element.css("top"),10)+(m.position.top-m.originalPosition.top))||null;if(!i.animate){this.element.css(c.extend(n,{top:l,left:j}))}m.helper.height(m.size.height);m.helper.width(m.size.width);if(this._helper&&!i.animate){this._proportionallyResize()}}c("body").css("cursor","auto");this.element.removeClass("ui-resizable-resizing");this._propagate("stop",h);if(this._helper){this.helper.remove()}return false},_updateVirtualBoundaries:function(g){var j=this.options,i,h,f,k,e;e={minWidth:a(j.minWidth)?j.minWidth:0,maxWidth:a(j.maxWidth)?j.maxWidth:Infinity,minHeight:a(j.minHeight)?j.minHeight:0,maxHeight:a(j.maxHeight)?j.maxHeight:Infinity};if(this._aspectRatio||g){i=e.minHeight*this.aspectRatio;f=e.minWidth/this.aspectRatio;h=e.maxHeight*this.aspectRatio;k=e.maxWidth/this.aspectRatio;if(i>e.minWidth){e.minWidth=i}if(f>e.minHeight){e.minHeight=f}if(hl.width),s=a(l.height)&&i.minHeight&&(i.minHeight>l.height);if(h){l.width=i.minWidth}if(s){l.height=i.minHeight}if(t){l.width=i.maxWidth}if(m){l.height=i.maxHeight}var f=this.originalPosition.left+this.originalSize.width,p=this.position.top+this.size.height;var k=/sw|nw|w/.test(q),e=/nw|ne|n/.test(q);if(h&&k){l.left=f-i.minWidth}if(t&&k){l.left=f-i.maxWidth}if(s&&e){l.top=p-i.minHeight}if(m&&e){l.top=p-i.maxHeight}var n=!l.width&&!l.height;if(n&&!l.left&&l.top){l.top=null}else{if(n&&!l.top&&l.left){l.left=null}}return l},_proportionallyResize:function(){var k=this.options;if(!this._proportionallyResizeElements.length){return}var g=this.helper||this.element;for(var f=0;f');var e=c.browser.msie&&c.browser.version<7,g=(e?1:0),h=(e?2:-1);this.helper.addClass(this._helper).css({width:this.element.outerWidth()+h,height:this.element.outerHeight()+h,position:"absolute",left:this.elementOffset.left-g+"px",top:this.elementOffset.top-g+"px",zIndex:++i.zIndex});this.helper.appendTo("body").disableSelection()}else{this.helper=this.element}},_change:{e:function(g,f,e){return{width:this.originalSize.width+f}},w:function(h,f,e){var j=this.options,g=this.originalSize,i=this.originalPosition;return{left:i.left+f,width:g.width-f}},n:function(h,f,e){var j=this.options,g=this.originalSize,i=this.originalPosition;return{top:i.top+e,height:g.height-e}},s:function(g,f,e){return{height:this.originalSize.height+e}},se:function(g,f,e){return c.extend(this._change.s.apply(this,arguments),this._change.e.apply(this,[g,f,e]))},sw:function(g,f,e){return c.extend(this._change.s.apply(this,arguments),this._change.w.apply(this,[g,f,e]))},ne:function(g,f,e){return c.extend(this._change.n.apply(this,arguments),this._change.e.apply(this,[g,f,e]))},nw:function(g,f,e){return c.extend(this._change.n.apply(this,arguments),this._change.w.apply(this,[g,f,e]))}},_propagate:function(f,e){c.ui.plugin.call(this,f,[e,this.ui()]);(f!="resize"&&this._trigger(f,e,this.ui()))},plugins:{},ui:function(){return{originalElement:this.originalElement,element:this.element,helper:this.helper,position:this.position,size:this.size,originalSize:this.originalSize,originalPosition:this.originalPosition}}});c.extend(c.ui.resizable,{version:"1.8.18"});c.ui.plugin.add("resizable","alsoResize",{start:function(f,g){var e=c(this).data("resizable"),i=e.options;var h=function(j){c(j).each(function(){var k=c(this);k.data("resizable-alsoresize",{width:parseInt(k.width(),10),height:parseInt(k.height(),10),left:parseInt(k.css("left"),10),top:parseInt(k.css("top"),10)})})};if(typeof(i.alsoResize)=="object"&&!i.alsoResize.parentNode){if(i.alsoResize.length){i.alsoResize=i.alsoResize[0];h(i.alsoResize)}else{c.each(i.alsoResize,function(j){h(j)})}}else{h(i.alsoResize)}},resize:function(g,i){var f=c(this).data("resizable"),j=f.options,h=f.originalSize,l=f.originalPosition;var k={height:(f.size.height-h.height)||0,width:(f.size.width-h.width)||0,top:(f.position.top-l.top)||0,left:(f.position.left-l.left)||0},e=function(m,n){c(m).each(function(){var q=c(this),r=c(this).data("resizable-alsoresize"),p={},o=n&&n.length?n:q.parents(i.originalElement[0]).length?["width","height"]:["width","height","top","left"];c.each(o,function(s,u){var t=(r[u]||0)+(k[u]||0);if(t&&t>=0){p[u]=t||null}});q.css(p)})};if(typeof(j.alsoResize)=="object"&&!j.alsoResize.nodeType){c.each(j.alsoResize,function(m,n){e(m,n)})}else{e(j.alsoResize)}},stop:function(e,f){c(this).removeData("resizable-alsoresize")}});c.ui.plugin.add("resizable","animate",{stop:function(i,n){var p=c(this).data("resizable"),j=p.options;var h=p._proportionallyResizeElements,e=h.length&&(/textarea/i).test(h[0].nodeName),f=e&&c.ui.hasScroll(h[0],"left")?0:p.sizeDiff.height,l=e?0:p.sizeDiff.width;var g={width:(p.size.width-l),height:(p.size.height-f)},k=(parseInt(p.element.css("left"),10)+(p.position.left-p.originalPosition.left))||null,m=(parseInt(p.element.css("top"),10)+(p.position.top-p.originalPosition.top))||null;p.element.animate(c.extend(g,m&&k?{top:m,left:k}:{}),{duration:j.animateDuration,easing:j.animateEasing,step:function(){var o={width:parseInt(p.element.css("width"),10),height:parseInt(p.element.css("height"),10),top:parseInt(p.element.css("top"),10),left:parseInt(p.element.css("left"),10)};if(h&&h.length){c(h[0]).css({width:o.width,height:o.height})}p._updateCache(o);p._propagate("resize",i)}})}});c.ui.plugin.add("resizable","containment",{start:function(f,r){var t=c(this).data("resizable"),j=t.options,l=t.element;var g=j.containment,k=(g instanceof c)?g.get(0):(/parent/.test(g))?l.parent().get(0):g;if(!k){return}t.containerElement=c(k);if(/document/.test(g)||g==document){t.containerOffset={left:0,top:0};t.containerPosition={left:0,top:0};t.parentData={element:c(document),left:0,top:0,width:c(document).width(),height:c(document).height()||document.body.parentNode.scrollHeight}}else{var n=c(k),i=[];c(["Top","Right","Left","Bottom"]).each(function(p,o){i[p]=b(n.css("padding"+o))});t.containerOffset=n.offset();t.containerPosition=n.position();t.containerSize={height:(n.innerHeight()-i[3]),width:(n.innerWidth()-i[1])};var q=t.containerOffset,e=t.containerSize.height,m=t.containerSize.width,h=(c.ui.hasScroll(k,"left")?k.scrollWidth:m),s=(c.ui.hasScroll(k)?k.scrollHeight:e);t.parentData={element:k,left:q.left,top:q.top,width:h,height:s}}},resize:function(g,q){var t=c(this).data("resizable"),i=t.options,f=t.containerSize,p=t.containerOffset,m=t.size,n=t.position,r=t._aspectRatio||g.shiftKey,e={top:0,left:0},h=t.containerElement;if(h[0]!=document&&(/static/).test(h.css("position"))){e=p}if(n.left<(t._helper?p.left:0)){t.size.width=t.size.width+(t._helper?(t.position.left-p.left):(t.position.left-e.left));if(r){t.size.height=t.size.width/i.aspectRatio}t.position.left=i.helper?p.left:0}if(n.top<(t._helper?p.top:0)){t.size.height=t.size.height+(t._helper?(t.position.top-p.top):t.position.top);if(r){t.size.width=t.size.height*i.aspectRatio}t.position.top=t._helper?p.top:0}t.offset.left=t.parentData.left+t.position.left;t.offset.top=t.parentData.top+t.position.top;var l=Math.abs((t._helper?t.offset.left-e.left:(t.offset.left-e.left))+t.sizeDiff.width),s=Math.abs((t._helper?t.offset.top-e.top:(t.offset.top-p.top))+t.sizeDiff.height);var k=t.containerElement.get(0)==t.element.parent().get(0),j=/relative|absolute/.test(t.containerElement.css("position"));if(k&&j){l-=t.parentData.left}if(l+t.size.width>=t.parentData.width){t.size.width=t.parentData.width-l;if(r){t.size.height=t.size.width/t.aspectRatio}}if(s+t.size.height>=t.parentData.height){t.size.height=t.parentData.height-s;if(r){t.size.width=t.size.height*t.aspectRatio}}},stop:function(f,n){var q=c(this).data("resizable"),g=q.options,l=q.position,m=q.containerOffset,e=q.containerPosition,i=q.containerElement;var j=c(q.helper),r=j.offset(),p=j.outerWidth()-q.sizeDiff.width,k=j.outerHeight()-q.sizeDiff.height;if(q._helper&&!g.animate&&(/relative/).test(i.css("position"))){c(this).css({left:r.left-e.left-m.left,width:p,height:k})}if(q._helper&&!g.animate&&(/static/).test(i.css("position"))){c(this).css({left:r.left-e.left-m.left,width:p,height:k})}}});c.ui.plugin.add("resizable","ghost",{start:function(g,h){var e=c(this).data("resizable"),i=e.options,f=e.size;e.ghost=e.originalElement.clone();e.ghost.css({opacity:0.25,display:"block",position:"relative",height:f.height,width:f.width,margin:0,left:0,top:0}).addClass("ui-resizable-ghost").addClass(typeof i.ghost=="string"?i.ghost:"");e.ghost.appendTo(e.helper)},resize:function(f,g){var e=c(this).data("resizable"),h=e.options;if(e.ghost){e.ghost.css({position:"relative",height:e.size.height,width:e.size.width})}},stop:function(f,g){var e=c(this).data("resizable"),h=e.options;if(e.ghost&&e.helper){e.helper.get(0).removeChild(e.ghost.get(0))}}});c.ui.plugin.add("resizable","grid",{resize:function(e,m){var p=c(this).data("resizable"),h=p.options,k=p.size,i=p.originalSize,j=p.originalPosition,n=p.axis,l=h._aspectRatio||e.shiftKey;h.grid=typeof h.grid=="number"?[h.grid,h.grid]:h.grid;var g=Math.round((k.width-i.width)/(h.grid[0]||1))*(h.grid[0]||1),f=Math.round((k.height-i.height)/(h.grid[1]||1))*(h.grid[1]||1);if(/^(se|s|e)$/.test(n)){p.size.width=i.width+g;p.size.height=i.height+f}else{if(/^(ne)$/.test(n)){p.size.width=i.width+g;p.size.height=i.height+f;p.position.top=j.top-f}else{if(/^(sw)$/.test(n)){p.size.width=i.width+g;p.size.height=i.height+f;p.position.left=j.left-g}else{p.size.width=i.width+g;p.size.height=i.height+f;p.position.top=j.top-f;p.position.left=j.left-g}}}}});var b=function(e){return parseInt(e,10)||0};var a=function(e){return !isNaN(parseInt(e,10))}})(jQuery);/*! + * jQuery hashchange event - v1.3 - 7/21/2010 + * http://benalman.com/projects/jquery-hashchange-plugin/ + * + * Copyright (c) 2010 "Cowboy" Ben Alman + * Dual licensed under the MIT and GPL licenses. + * http://benalman.com/about/license/ + */ +(function($,e,b){var c="hashchange",h=document,f,g=$.event.special,i=h.documentMode,d="on"+c in e&&(i===b||i>7);function a(j){j=j||location.href;return"#"+j.replace(/^[^#]*#?(.*)$/,"$1")}$.fn[c]=function(j){return j?this.bind(c,j):this.trigger(c)};$.fn[c].delay=50;g[c]=$.extend(g[c],{setup:function(){if(d){return false}$(f.start)},teardown:function(){if(d){return false}$(f.stop)}});f=(function(){var j={},p,m=a(),k=function(q){return q},l=k,o=k;j.start=function(){p||n()};j.stop=function(){p&&clearTimeout(p);p=b};function n(){var r=a(),q=o(m);if(r!==m){l(m=r,q);$(e).trigger(c)}else{if(q!==m){location.href=location.href.replace(/#.*/,"")+q}}p=setTimeout(n,$.fn[c].delay)}$.browser.msie&&!d&&(function(){var q,r;j.start=function(){if(!q){r=$.fn[c].src;r=r&&r+a();q=$(' + + + + +
+ +
+
keystore.h File Reference
+
+
+ +

KeyStore is a container for keys and certificates. +More...

+
#include <openssl/ossl_typ.h>
+#include <stddef.h>
+
+

Go to the source code of this file.

+
+ + + + +

+Typedefs

+typedef struct KeyStore_st KeyStore
 KeyStore container handle. It owns all keys and certificates inside.
 
+ + + + + + + + + + + + + + + + +

+Functions

void KeyStoreFree (KeyStore *ks)
 destroys KeyStore data. More...
 
size_t KeyStoreKeyNum (const KeyStore *ks)
 returns a number of entries for keys allocated inside the KeyStore. More...
 
size_t KeyStoreCertNum (const KeyStore *ks)
 returns a number of entries for certificates allocated inside the KeyStore. More...
 
const EVP_PKEY * KeyStoreGetKey (const KeyStore *ks, size_t pos)
 returns a pointer to the key entry number 'pos'. The first entry is 0. More...
 
const X509 * KeyStoreGetCert (const KeyStore *ks, size_t pos)
 returns a pointer to the cert entry number 'pos'. The first entry is 0. More...
 
+

Detailed Description

+

KeyStore is a container for keys and certificates.

+

Function Documentation

+ +

◆ KeyStoreCertNum()

+ +
+
+ + + + + + + + +
size_t KeyStoreCertNum (const KeyStoreks)
+
+ +

returns a number of entries for certificates allocated inside the KeyStore.

+
Parameters
+ + +
ksKeyStore handle.
+
+
+
Returns
the number of cert entries in the store.
+ +
+
+ +

◆ KeyStoreFree()

+ +
+
+ + + + + + + + +
void KeyStoreFree (KeyStoreks)
+
+ +

destroys KeyStore data.

+
Parameters
+ + +
ksKeyStore handle;
+
+
+ +
+
+ +

◆ KeyStoreGetCert()

+ +
+
+ + + + + + + + + + + + + + + + + + +
const X509 * KeyStoreGetCert (const KeyStoreks,
size_t pos 
)
+
+ +

returns a pointer to the cert entry number 'pos'. The first entry is 0.

+
Parameters
+ + + +
ksKeyStore handle;
poscert entry number starting from 0.
+
+
+
Returns
the pointer to the cert entry.
+ +
+
+ +

◆ KeyStoreGetKey()

+ +
+
+ + + + + + + + + + + + + + + + + + +
const EVP_PKEY * KeyStoreGetKey (const KeyStoreks,
size_t pos 
)
+
+ +

returns a pointer to the key entry number 'pos'. The first entry is 0.

+
Parameters
+ + + +
ksKeyStore handle;
poskey entry number starting from 0.
+
+
+
Returns
the pointer to the key entry.
+ +
+
+ +

◆ KeyStoreKeyNum()

+ +
+
+ + + + + + + + +
size_t KeyStoreKeyNum (const KeyStoreks)
+
+ +

returns a number of entries for keys allocated inside the KeyStore.

+
Parameters
+ + +
ksKeyStore handle.
+
+
+
Returns
the number of key entries in the store.
+ +
+
+
+ + + + diff --git a/docs/keystore_8h_source.html b/docs/keystore_8h_source.html new file mode 100644 index 0000000..0745b3c --- /dev/null +++ b/docs/keystore_8h_source.html @@ -0,0 +1,84 @@ + + + + + + + +Keylib: keylib/keystore.h Source File + + + + + + + + + +
+
+ + + + + + +
+
Keylib +
+
Library for reading OpenSSL keys from different containers.
+
+
+ + + + + + + + +
+
+ + +
+ +
+ + +
+
+
+
keystore.h
+
+
+Go to the documentation of this file.
1 #pragma once
2 
7 #include <openssl/ossl_typ.h>
8 
9 #include <stddef.h>
10 
11 #ifdef __cplusplus
12 extern "C" {
13 #endif
14 
18 typedef struct KeyStore_st KeyStore;
19 
24 void KeyStoreFree(KeyStore* ks);
25 
31 size_t KeyStoreKeyNum(const KeyStore* ks);
32 
38 size_t KeyStoreCertNum(const KeyStore* ks);
39 
46 const EVP_PKEY* KeyStoreGetKey(const KeyStore* ks, size_t pos);
47 
54 const X509* KeyStoreGetCert(const KeyStore* ks, size_t pos);
55 
56 #ifdef __cplusplus
57 }
58 #endif
void KeyStoreFree(KeyStore *ks)
destroys KeyStore data.
+
const EVP_PKEY * KeyStoreGetKey(const KeyStore *ks, size_t pos)
returns a pointer to the key entry number &#39;pos&#39;. The first entry is 0.
+
struct KeyStore_st KeyStore
KeyStore container handle. It owns all keys and certificates inside.
Definition: keystore.h:18
+
const X509 * KeyStoreGetCert(const KeyStore *ks, size_t pos)
returns a pointer to the cert entry number &#39;pos&#39;. The first entry is 0.
+
size_t KeyStoreKeyNum(const KeyStore *ks)
returns a number of entries for keys allocated inside the KeyStore.
+
size_t KeyStoreCertNum(const KeyStore *ks)
returns a number of entries for certificates allocated inside the KeyStore.
+
+ + + + diff --git a/docs/menu.js b/docs/menu.js index 433c15b..97db4c2 100644 --- a/docs/menu.js +++ b/docs/menu.js @@ -1,26 +1,3 @@ -/* - @licstart The following is the entire license notice for the - JavaScript code in this file. - - Copyright (C) 1997-2017 by Dimitri van Heesch - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License along - with this program; if not, write to the Free Software Foundation, Inc., - 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - - @licend The above is the entire license notice - for the JavaScript code in this file - */ function initMenu(relPath,searchEnabled,serverSide,searchPage,search) { function makeTree(data,relPath) { var result=''; @@ -40,11 +17,10 @@ function initMenu(relPath,searchEnabled,serverSide,searchPage,search) { $('#main-nav').children(':first').addClass('sm sm-dox').attr('id','main-menu'); if (searchEnabled) { if (serverSide) { - $('#main-menu').append('
  • '); + $('#main-menu').append('
  • '); } else { $('#main-menu').append('
  • '); } } $('#main-menu').smartmenus(); } -/* @license-end */ diff --git a/docs/menudata.js b/docs/menudata.js index 3fda59c..232463d 100644 --- a/docs/menudata.js +++ b/docs/menudata.js @@ -1,25 +1,3 @@ -/* -@licstart The following is the entire license notice for the -JavaScript code in this file. - -Copyright (C) 1997-2019 by Dimitri van Heesch - -This program is free software; you can redistribute it and/or modify -it under the terms of version 2 of the GNU General Public License as published by -the Free Software Foundation - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License along -with this program; if not, write to the Free Software Foundation, Inc., -51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - -@licend The above is the entire license notice -for the JavaScript code in this file -*/ var menudata={children:[ {text:"Main Page",url:"index.html"}, {text:"Files",url:"files.html",children:[ @@ -27,5 +5,4 @@ var menudata={children:[ {text:"File Members",url:"globals.html",children:[ {text:"All",url:"globals.html"}, {text:"Functions",url:"globals_func.html"}, -{text:"Typedefs",url:"globals_type.html"}, -{text:"Macros",url:"globals_defs.html"}]}]}]} +{text:"Typedefs",url:"globals_type.html"}]}]}]} diff --git a/docs/pkcs12_8h.html b/docs/pkcs12_8h.html new file mode 100644 index 0000000..08a31b7 --- /dev/null +++ b/docs/pkcs12_8h.html @@ -0,0 +1,267 @@ + + + + + + + +Keylib: keylib/pkcs12.h File Reference + + + + + + + + + +
    +
    + + + + + + +
    +
    Keylib +
    +
    Library for reading OpenSSL keys from different containers.
    +
    +
    + + + + + + + + +
    +
    + + +
    + +
    + + +
    +
    + +
    +
    pkcs12.h File Reference
    +
    +
    + +

    Functions for reading keys from PKCS#12 container. +More...

    +
    #include "keystore.h"
    +#include <openssl/ossl_typ.h>
    +#include <stdio.h>
    +
    +

    Go to the source code of this file.

    + + + + + + + + + + + +

    +Functions

    int parsePKCS12 (const void *data, size_t dataSize, const char *password, size_t passSize, KeyStore **ks)
     extracts private keys from PKCS#12 container. More...
     
    int readPKCS12 (FILE *fp, const char *password, size_t passSize, KeyStore **ks)
     extracts private keys from PKCS#12 container. More...
     
    int readPKCS12_bio (BIO *bio, const char *password, size_t passSize, KeyStore **ks)
     extracts private keys from PKCS#12 container. More...
     
    +

    Detailed Description

    +

    Functions for reading keys from PKCS#12 container.

    +

    Function Documentation

    + +

    ◆ parsePKCS12()

    + +
    +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    int parsePKCS12 (const void * data,
    size_t size,
    const char * password,
    size_t passSize,
    KeyStore ** ks 
    )
    +
    + +

    extracts private keys from PKCS#12 container.

    +
    Parameters
    + + + + + + +
    datacontainer data;
    sizecontainer data size;
    passwordcontainer encryption password;
    passSizepassword size;
    ksKeyStore pointer outparam.
    +
    +
    +
    Returns
    1 for success, 0 in case of failure.
    + +
    +
    + +

    ◆ readPKCS12()

    + +
    +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    int readPKCS12 (FILE * fp,
    const char * password,
    size_t passSize,
    KeyStore ** ks 
    )
    +
    + +

    extracts private keys from PKCS#12 container.

    +
    Parameters
    + + + + + +
    fpfile handle;
    passwordcontainer encryption password;
    passSizepassword size;
    ksKeyStore pointer outparam.
    +
    +
    +
    Returns
    1 for success, 0 in case of failure.
    + +
    +
    + +

    ◆ readPKCS12_bio()

    + +
    +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    int readPKCS12_bio (BIO * bio,
    const char * password,
    size_t passSize,
    KeyStore ** ks 
    )
    +
    + +

    extracts private keys from PKCS#12 container.

    +
    Parameters
    + + + + + +
    bioOpenSSL BIO;
    passwordcontainer encryption password;
    passSizepassword size;
    ksKeyStore pointer outparam.
    +
    +
    +
    Returns
    1 for success, 0 in case of failure.
    + +
    +
    +
    + + + + diff --git a/docs/pkcs12_8h_source.html b/docs/pkcs12_8h_source.html new file mode 100644 index 0000000..d1aff46 --- /dev/null +++ b/docs/pkcs12_8h_source.html @@ -0,0 +1,83 @@ + + + + + + + +Keylib: keylib/pkcs12.h Source File + + + + + + + + + +
    +
    + + + + + + +
    +
    Keylib +
    +
    Library for reading OpenSSL keys from different containers.
    +
    +
    + + + + + + + + +
    +
    + + +
    + +
    + + +
    +
    +
    +
    pkcs12.h
    +
    +
    +Go to the documentation of this file.
    1 #pragma once
    2 
    7 #include "keystore.h"
    8 
    9 #include <openssl/ossl_typ.h>
    10 
    11 #include <stdio.h>
    12 
    13 #ifdef __cplusplus
    14 extern "C" {
    15 #endif
    16 
    26 int parsePKCS12(const void* data, size_t dataSize, const char* password, size_t passSize, KeyStore** ks);
    27 
    36 int readPKCS12(FILE* fp, const char* password, size_t passSize, KeyStore** ks);
    37 
    46 int readPKCS12_bio(BIO* bio, const char* password, size_t passSize, KeyStore** ks);
    47 
    48 #ifdef __cplusplus
    49 }
    50 #endif
    int readPKCS12_bio(BIO *bio, const char *password, size_t passSize, KeyStore **ks)
    extracts private keys from PKCS#12 container.
    +
    struct KeyStore_st KeyStore
    KeyStore container handle. It owns all keys and certificates inside.
    Definition: keystore.h:18
    +
    KeyStore is a container for keys and certificates.
    +
    int parsePKCS12(const void *data, size_t dataSize, const char *password, size_t passSize, KeyStore **ks)
    extracts private keys from PKCS#12 container.
    +
    int readPKCS12(FILE *fp, const char *password, size_t passSize, KeyStore **ks)
    extracts private keys from PKCS#12 container.
    +
    + + + + diff --git a/docs/search/all_0.html b/docs/search/all_0.html index 26dd244..f25360b 100644 --- a/docs/search/all_0.html +++ b/docs/search/all_0.html @@ -1,7 +1,7 @@ - + - + @@ -11,19 +11,15 @@
    Loading...
    Searching...
    No Matches
    diff --git a/docs/search/all_0.js b/docs/search/all_0.js index 14c6b9c..95a107c 100644 --- a/docs/search/all_0.js +++ b/docs/search/all_0.js @@ -1,22 +1,4 @@ var searchData= [ - ['jks_0',['JKS',['../jks_8h.html#aebc768be95622e6a19163a900a103145',1,'jks.h']]], - ['jks_2eh_1',['jks.h',['../jks_8h.html',1,'']]], - ['jks_5fentry_5fcert_2',['JKS_ENTRY_CERT',['../jks_8h.html#a269ec63648a88ddbce1d207f9651e425',1,'jks.h']]], - ['jks_5fentry_5fprivate_5fkey_3',['JKS_ENTRY_PRIVATE_KEY',['../jks_8h.html#a14186bea17cf6f836958ac2bc61f9ef7',1,'jks.h']]], - ['jks_5ftype_5fjceks_4',['JKS_TYPE_JCEKS',['../jks_8h.html#a432f328d5059d05aae837646c32a6b98',1,'jks.h']]], - ['jks_5ftype_5fjks_5',['JKS_TYPE_JKS',['../jks_8h.html#abcf986ce752a22926dfc05bc608356a0',1,'jks.h']]], - ['jksentry_6',['JKSEntry',['../jks_8h.html#a79bb2765b2fd9f6bc732c391282a4a4f',1,'jks.h']]], - ['jksentrycert_7',['JKSEntryCert',['../jks_8h.html#a7ef7f4a51a628ba1a49e0553d8de76c7',1,'jks.h']]], - ['jksentrycertnum_8',['JKSEntryCertNum',['../jks_8h.html#ac9a3fdb3c14a9b3446c9cfc01f56319b',1,'jks.h']]], - ['jksentrycerttype_9',['JKSEntryCertType',['../jks_8h.html#a3159033ff83154a1934ace0691d09d39',1,'jks.h']]], - ['jksentrydecrypt_10',['JKSEntryDecrypt',['../jks_8h.html#a4f09e453c22e8668aa6d47369323ab84',1,'jks.h']]], - ['jksentryget_11',['JKSEntryGet',['../jks_8h.html#abecc1140c363d8f09a5a3b3f2badd0fd',1,'jks.h']]], - ['jksentrynum_12',['JKSEntryNum',['../jks_8h.html#a03cbe0a401f2f9620f87a29e2d5dd9c3',1,'jks.h']]], - ['jksentrypkey_13',['JKSEntryPKey',['../jks_8h.html#a12b0ca6d4001c07a20f3baf543eadc1a',1,'jks.h']]], - ['jksentrypkeyname_14',['JKSEntryPKeyName',['../jks_8h.html#aec4b66d18162a58f3a38e5ec7c9fe523',1,'jks.h']]], - ['jksentrypkeynum_15',['JKSEntryPKeyNum',['../jks_8h.html#ab10f67cf80d0ac3c75ae5da364ca3f95',1,'jks.h']]], - ['jksentrytype_16',['JKSEntryType',['../jks_8h.html#a917162ae2c788bcaabfeb47354fbbc05',1,'jks.h']]], - ['jksfree_17',['JKSFree',['../jks_8h.html#a7c9b8a0d0b696c2ca8e750440cd7d9d4',1,'jks.h']]], - ['jkstype_18',['JKSType',['../jks_8h.html#adae7853d0dfacfc11e8fa239d06d0176',1,'jks.h']]] + ['jks_2eh',['jks.h',['../jks_8h.html',1,'']]] ]; diff --git a/docs/search/all_1.html b/docs/search/all_1.html index 8eb215b..b13f0f7 100644 --- a/docs/search/all_1.html +++ b/docs/search/all_1.html @@ -1,7 +1,7 @@ - + - + @@ -11,19 +11,15 @@
    Loading...
    Searching...
    No Matches
    diff --git a/docs/search/all_1.js b/docs/search/all_1.js index 09e417b..5ee4fdc 100644 --- a/docs/search/all_1.js +++ b/docs/search/all_1.js @@ -1,4 +1,11 @@ var searchData= [ - ['key6_2eh_19',['key6.h',['../key6_8h.html',1,'']]] + ['key6_2eh',['key6.h',['../key6_8h.html',1,'']]], + ['keystore',['KeyStore',['../keystore_8h.html#a47001241c3170d4d172af46d23cee0af',1,'keystore.h']]], + ['keystore_2eh',['keystore.h',['../keystore_8h.html',1,'']]], + ['keystorecertnum',['KeyStoreCertNum',['../keystore_8h.html#a359442f86f77b1fa715625018445596b',1,'keystore.h']]], + ['keystorefree',['KeyStoreFree',['../keystore_8h.html#ad15cfd5ffc36c08b47bdf6a2c093db9d',1,'keystore.h']]], + ['keystoregetcert',['KeyStoreGetCert',['../keystore_8h.html#adb6aa0a87a685c80bb583f751568ff8c',1,'keystore.h']]], + ['keystoregetkey',['KeyStoreGetKey',['../keystore_8h.html#a2ad4de9e1e849195f30fc1bd79183363',1,'keystore.h']]], + ['keystorekeynum',['KeyStoreKeyNum',['../keystore_8h.html#aa5e987354ce48eb567b65e08ddcdb9bb',1,'keystore.h']]] ]; diff --git a/docs/search/all_2.html b/docs/search/all_2.html index b26d916..9543c57 100644 --- a/docs/search/all_2.html +++ b/docs/search/all_2.html @@ -1,7 +1,7 @@ - + - + @@ -11,19 +11,15 @@
    Loading...
    Searching...
    No Matches
    diff --git a/docs/search/all_2.js b/docs/search/all_2.js index e58a207..5474e7e 100644 --- a/docs/search/all_2.js +++ b/docs/search/all_2.js @@ -1,5 +1,7 @@ var searchData= [ - ['parsejks_20',['parseJKS',['../jks_8h.html#a6c31b3d93e9374d8aaac4e196b0ace55',1,'jks.h']]], - ['parsekey6_21',['parseKey6',['../key6_8h.html#aafa74cfa2b74f1e01663912b549b48af',1,'key6.h']]] + ['parsejks',['parseJKS',['../jks_8h.html#a73148d729be88fd3c853c927328f2ff4',1,'jks.h']]], + ['parsekey6',['parseKey6',['../key6_8h.html#ab1b43c31421e8305eba1d015eb200d52',1,'key6.h']]], + ['parsepkcs12',['parsePKCS12',['../pkcs12_8h.html#a0412a92e5772d3f4b2e0e7dd43668c5c',1,'pkcs12.h']]], + ['pkcs12_2eh',['pkcs12.h',['../pkcs12_8h.html',1,'']]] ]; diff --git a/docs/search/all_3.html b/docs/search/all_3.html index b61b96f..03405c0 100644 --- a/docs/search/all_3.html +++ b/docs/search/all_3.html @@ -1,7 +1,7 @@ - + - + @@ -11,19 +11,15 @@
    Loading...
    Searching...
    No Matches
    diff --git a/docs/search/all_3.js b/docs/search/all_3.js index 0052f8d..454d9e1 100644 --- a/docs/search/all_3.js +++ b/docs/search/all_3.js @@ -1,7 +1,9 @@ var searchData= [ - ['readjks_22',['readJKS',['../jks_8h.html#ace15f7b12d5d0e9e3caaf082b177189d',1,'jks.h']]], - ['readjks_5fbio_23',['readJKS_bio',['../jks_8h.html#aaa67ca72a912a18887bc7e25077bcf2e',1,'jks.h']]], - ['readkey6_24',['readKey6',['../key6_8h.html#a3d1724884e0502cbb7c6d5b0496c4fb4',1,'key6.h']]], - ['readkey6_5fbio_25',['readKey6_bio',['../key6_8h.html#a116d1ca6e05c5c87f34abd473abb7f24',1,'key6.h']]] + ['readjks',['readJKS',['../jks_8h.html#abfeec227577e7615660745534eb24f32',1,'jks.h']]], + ['readjks_5fbio',['readJKS_bio',['../jks_8h.html#a2c8373198da78bba1ec0a727c81bcf47',1,'jks.h']]], + ['readkey6',['readKey6',['../key6_8h.html#a6e2549d17f44170c620d4dc99ed9e598',1,'key6.h']]], + ['readkey6_5fbio',['readKey6_bio',['../key6_8h.html#adfb470246da474f83baaaf75485f45c0',1,'key6.h']]], + ['readpkcs12',['readPKCS12',['../pkcs12_8h.html#aa13551df353ae35640b482a4459b3110',1,'pkcs12.h']]], + ['readpkcs12_5fbio',['readPKCS12_bio',['../pkcs12_8h.html#a338e99eab360e7609fe878b2b22b0f54',1,'pkcs12.h']]] ]; diff --git a/docs/search/files_0.html b/docs/search/files_0.html index 737608e..4f272b8 100644 --- a/docs/search/files_0.html +++ b/docs/search/files_0.html @@ -1,7 +1,7 @@ - + - + @@ -11,19 +11,15 @@
    Loading...
    Searching...
    No Matches
    diff --git a/docs/search/files_0.js b/docs/search/files_0.js index 2d5f0fd..95a107c 100644 --- a/docs/search/files_0.js +++ b/docs/search/files_0.js @@ -1,4 +1,4 @@ var searchData= [ - ['jks_2eh_26',['jks.h',['../jks_8h.html',1,'']]] + ['jks_2eh',['jks.h',['../jks_8h.html',1,'']]] ]; diff --git a/docs/search/files_1.html b/docs/search/files_1.html index f27a62d..dcce422 100644 --- a/docs/search/files_1.html +++ b/docs/search/files_1.html @@ -1,7 +1,7 @@ - + - + @@ -11,19 +11,15 @@
    Loading...
    Searching...
    No Matches
    diff --git a/docs/search/files_1.js b/docs/search/files_1.js index 973d7e8..fba28d0 100644 --- a/docs/search/files_1.js +++ b/docs/search/files_1.js @@ -1,4 +1,5 @@ var searchData= [ - ['key6_2eh_27',['key6.h',['../key6_8h.html',1,'']]] + ['key6_2eh',['key6.h',['../key6_8h.html',1,'']]], + ['keystore_2eh',['keystore.h',['../keystore_8h.html',1,'']]] ]; diff --git a/docs/search/files_2.html b/docs/search/files_2.html new file mode 100644 index 0000000..d5c6c3b --- /dev/null +++ b/docs/search/files_2.html @@ -0,0 +1,26 @@ + + + + + + + + + +
    +
    Loading...
    +
    + +
    Searching...
    +
    No Matches
    + +
    + + diff --git a/docs/search/files_2.js b/docs/search/files_2.js new file mode 100644 index 0000000..62f9c1f --- /dev/null +++ b/docs/search/files_2.js @@ -0,0 +1,4 @@ +var searchData= +[ + ['pkcs12_2eh',['pkcs12.h',['../pkcs12_8h.html',1,'']]] +]; diff --git a/docs/search/functions_0.html b/docs/search/functions_0.html index e17c711..4e6d87d 100644 --- a/docs/search/functions_0.html +++ b/docs/search/functions_0.html @@ -1,7 +1,7 @@ - + - + @@ -11,19 +11,15 @@
    Loading...
    Searching...
    No Matches
    diff --git a/docs/search/functions_0.js b/docs/search/functions_0.js index 1329058..75af84d 100644 --- a/docs/search/functions_0.js +++ b/docs/search/functions_0.js @@ -1,15 +1,8 @@ var searchData= [ - ['jksentrycert_28',['JKSEntryCert',['../jks_8h.html#a7ef7f4a51a628ba1a49e0553d8de76c7',1,'jks.h']]], - ['jksentrycertnum_29',['JKSEntryCertNum',['../jks_8h.html#ac9a3fdb3c14a9b3446c9cfc01f56319b',1,'jks.h']]], - ['jksentrycerttype_30',['JKSEntryCertType',['../jks_8h.html#a3159033ff83154a1934ace0691d09d39',1,'jks.h']]], - ['jksentrydecrypt_31',['JKSEntryDecrypt',['../jks_8h.html#a4f09e453c22e8668aa6d47369323ab84',1,'jks.h']]], - ['jksentryget_32',['JKSEntryGet',['../jks_8h.html#abecc1140c363d8f09a5a3b3f2badd0fd',1,'jks.h']]], - ['jksentrynum_33',['JKSEntryNum',['../jks_8h.html#a03cbe0a401f2f9620f87a29e2d5dd9c3',1,'jks.h']]], - ['jksentrypkey_34',['JKSEntryPKey',['../jks_8h.html#a12b0ca6d4001c07a20f3baf543eadc1a',1,'jks.h']]], - ['jksentrypkeyname_35',['JKSEntryPKeyName',['../jks_8h.html#aec4b66d18162a58f3a38e5ec7c9fe523',1,'jks.h']]], - ['jksentrypkeynum_36',['JKSEntryPKeyNum',['../jks_8h.html#ab10f67cf80d0ac3c75ae5da364ca3f95',1,'jks.h']]], - ['jksentrytype_37',['JKSEntryType',['../jks_8h.html#a917162ae2c788bcaabfeb47354fbbc05',1,'jks.h']]], - ['jksfree_38',['JKSFree',['../jks_8h.html#a7c9b8a0d0b696c2ca8e750440cd7d9d4',1,'jks.h']]], - ['jkstype_39',['JKSType',['../jks_8h.html#adae7853d0dfacfc11e8fa239d06d0176',1,'jks.h']]] + ['keystorecertnum',['KeyStoreCertNum',['../keystore_8h.html#a359442f86f77b1fa715625018445596b',1,'keystore.h']]], + ['keystorefree',['KeyStoreFree',['../keystore_8h.html#ad15cfd5ffc36c08b47bdf6a2c093db9d',1,'keystore.h']]], + ['keystoregetcert',['KeyStoreGetCert',['../keystore_8h.html#adb6aa0a87a685c80bb583f751568ff8c',1,'keystore.h']]], + ['keystoregetkey',['KeyStoreGetKey',['../keystore_8h.html#a2ad4de9e1e849195f30fc1bd79183363',1,'keystore.h']]], + ['keystorekeynum',['KeyStoreKeyNum',['../keystore_8h.html#aa5e987354ce48eb567b65e08ddcdb9bb',1,'keystore.h']]] ]; diff --git a/docs/search/functions_1.html b/docs/search/functions_1.html index 0ddac0a..b343e2d 100644 --- a/docs/search/functions_1.html +++ b/docs/search/functions_1.html @@ -1,7 +1,7 @@ - + - + @@ -11,19 +11,15 @@
    Loading...
    Searching...
    No Matches
    diff --git a/docs/search/functions_1.js b/docs/search/functions_1.js index 6129f72..a832c8c 100644 --- a/docs/search/functions_1.js +++ b/docs/search/functions_1.js @@ -1,5 +1,6 @@ var searchData= [ - ['parsejks_40',['parseJKS',['../jks_8h.html#a6c31b3d93e9374d8aaac4e196b0ace55',1,'jks.h']]], - ['parsekey6_41',['parseKey6',['../key6_8h.html#aafa74cfa2b74f1e01663912b549b48af',1,'key6.h']]] + ['parsejks',['parseJKS',['../jks_8h.html#a73148d729be88fd3c853c927328f2ff4',1,'jks.h']]], + ['parsekey6',['parseKey6',['../key6_8h.html#ab1b43c31421e8305eba1d015eb200d52',1,'key6.h']]], + ['parsepkcs12',['parsePKCS12',['../pkcs12_8h.html#a0412a92e5772d3f4b2e0e7dd43668c5c',1,'pkcs12.h']]] ]; diff --git a/docs/search/functions_2.html b/docs/search/functions_2.html index 2737c5a..ecce2f3 100644 --- a/docs/search/functions_2.html +++ b/docs/search/functions_2.html @@ -1,7 +1,7 @@ - + - + @@ -11,19 +11,15 @@
    Loading...
    Searching...
    No Matches
    diff --git a/docs/search/functions_2.js b/docs/search/functions_2.js index b6c6dc0..454d9e1 100644 --- a/docs/search/functions_2.js +++ b/docs/search/functions_2.js @@ -1,7 +1,9 @@ var searchData= [ - ['readjks_42',['readJKS',['../jks_8h.html#ace15f7b12d5d0e9e3caaf082b177189d',1,'jks.h']]], - ['readjks_5fbio_43',['readJKS_bio',['../jks_8h.html#aaa67ca72a912a18887bc7e25077bcf2e',1,'jks.h']]], - ['readkey6_44',['readKey6',['../key6_8h.html#a3d1724884e0502cbb7c6d5b0496c4fb4',1,'key6.h']]], - ['readkey6_5fbio_45',['readKey6_bio',['../key6_8h.html#a116d1ca6e05c5c87f34abd473abb7f24',1,'key6.h']]] + ['readjks',['readJKS',['../jks_8h.html#abfeec227577e7615660745534eb24f32',1,'jks.h']]], + ['readjks_5fbio',['readJKS_bio',['../jks_8h.html#a2c8373198da78bba1ec0a727c81bcf47',1,'jks.h']]], + ['readkey6',['readKey6',['../key6_8h.html#a6e2549d17f44170c620d4dc99ed9e598',1,'key6.h']]], + ['readkey6_5fbio',['readKey6_bio',['../key6_8h.html#adfb470246da474f83baaaf75485f45c0',1,'key6.h']]], + ['readpkcs12',['readPKCS12',['../pkcs12_8h.html#aa13551df353ae35640b482a4459b3110',1,'pkcs12.h']]], + ['readpkcs12_5fbio',['readPKCS12_bio',['../pkcs12_8h.html#a338e99eab360e7609fe878b2b22b0f54',1,'pkcs12.h']]] ]; diff --git a/docs/search/mag_sel.png b/docs/search/mag_sel.png index 39c0ed5..81f6040 100644 Binary files a/docs/search/mag_sel.png and b/docs/search/mag_sel.png differ diff --git a/docs/search/nomatches.html b/docs/search/nomatches.html index 4377320..b1ded27 100644 --- a/docs/search/nomatches.html +++ b/docs/search/nomatches.html @@ -1,4 +1,4 @@ - + diff --git a/docs/search/search.js b/docs/search/search.js index a554ab9..dedce3b 100644 --- a/docs/search/search.js +++ b/docs/search/search.js @@ -1,26 +1,3 @@ -/* - @licstart The following is the entire license notice for the - JavaScript code in this file. - - Copyright (C) 1997-2017 by Dimitri van Heesch - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License along - with this program; if not, write to the Free Software Foundation, Inc., - 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - - @licend The above is the entire license notice - for the JavaScript code in this file - */ function convertToId(search) { var result = ''; @@ -811,4 +788,4 @@ function init_search() } searchBox.OnSelectItem(0); } -/* @license-end */ + diff --git a/docs/search/search_l.png b/docs/search/search_l.png index fd5f7da..c872f4d 100644 Binary files a/docs/search/search_l.png and b/docs/search/search_l.png differ diff --git a/docs/search/search_r.png b/docs/search/search_r.png index 1af5d21..97ee8b4 100644 Binary files a/docs/search/search_r.png and b/docs/search/search_r.png differ diff --git a/docs/search/searchdata.js b/docs/search/searchdata.js index 13e289c..090f0fc 100644 --- a/docs/search/searchdata.js +++ b/docs/search/searchdata.js @@ -1,10 +1,9 @@ var indexSectionsWithContent = { 0: "jkpr", - 1: "jk", - 2: "jpr", - 3: "j", - 4: "j" + 1: "jkp", + 2: "kpr", + 3: "k" }; var indexSectionNames = @@ -12,8 +11,7 @@ var indexSectionNames = 0: "all", 1: "files", 2: "functions", - 3: "typedefs", - 4: "defines" + 3: "typedefs" }; var indexSectionLabels = @@ -21,7 +19,6 @@ var indexSectionLabels = 0: "All", 1: "Files", 2: "Functions", - 3: "Typedefs", - 4: "Macros" + 3: "Typedefs" }; diff --git a/docs/search/typedefs_0.html b/docs/search/typedefs_0.html index 376db47..05722e1 100644 --- a/docs/search/typedefs_0.html +++ b/docs/search/typedefs_0.html @@ -1,7 +1,7 @@ - + - + @@ -11,19 +11,15 @@
    Loading...
    Searching...
    No Matches
    diff --git a/docs/search/typedefs_0.js b/docs/search/typedefs_0.js index 20d7ec4..d5f232a 100644 --- a/docs/search/typedefs_0.js +++ b/docs/search/typedefs_0.js @@ -1,5 +1,4 @@ var searchData= [ - ['jks_46',['JKS',['../jks_8h.html#aebc768be95622e6a19163a900a103145',1,'jks.h']]], - ['jksentry_47',['JKSEntry',['../jks_8h.html#a79bb2765b2fd9f6bc732c391282a4a4f',1,'jks.h']]] + ['keystore',['KeyStore',['../keystore_8h.html#a47001241c3170d4d172af46d23cee0af',1,'keystore.h']]] ]; diff --git a/docs/tabs.css b/docs/tabs.css index 85a0cd5..bbde11e 100644 --- a/docs/tabs.css +++ b/docs/tabs.css @@ -1 +1 @@ -.sm{position:relative;z-index:9999}.sm,.sm ul,.sm li{display:block;list-style:none;margin:0;padding:0;line-height:normal;direction:ltr;text-align:left;-webkit-tap-highlight-color:rgba(0,0,0,0)}.sm-rtl,.sm-rtl ul,.sm-rtl li{direction:rtl;text-align:right}.sm>li>h1,.sm>li>h2,.sm>li>h3,.sm>li>h4,.sm>li>h5,.sm>li>h6{margin:0;padding:0}.sm ul{display:none}.sm li,.sm a{position:relative}.sm a{display:block}.sm a.disabled{cursor:not-allowed}.sm:after{content:"\00a0";display:block;height:0;font:0/0 serif;clear:both;visibility:hidden;overflow:hidden}.sm,.sm *,.sm *:before,.sm *:after{-moz-box-sizing:border-box;-webkit-box-sizing:border-box;box-sizing:border-box}.sm-dox{background-image:url("tab_b.png")}.sm-dox a,.sm-dox a:focus,.sm-dox a:hover,.sm-dox a:active{padding:0 12px;padding-right:43px;font-family:"Lucida Grande","Geneva","Helvetica",Arial,sans-serif;font-size:13px;font-weight:bold;line-height:36px;text-decoration:none;text-shadow:0 1px 1px rgba(255,255,255,0.9);color:#283a5d;outline:0}.sm-dox a:hover{background-image:url("tab_a.png");background-repeat:repeat-x;color:white;text-shadow:0 1px 1px black}.sm-dox a.current{color:#d23600}.sm-dox a.disabled{color:#bbb}.sm-dox a span.sub-arrow{position:absolute;top:50%;margin-top:-14px;left:auto;right:3px;width:28px;height:28px;overflow:hidden;font:bold 12px/28px monospace!important;text-align:center;text-shadow:none;background:rgba(255,255,255,0.5);-moz-border-radius:5px;-webkit-border-radius:5px;border-radius:5px}.sm-dox a.highlighted span.sub-arrow:before{display:block;content:'-'}.sm-dox>li:first-child>a,.sm-dox>li:first-child>:not(ul) a{-moz-border-radius:5px 5px 0 0;-webkit-border-radius:5px;border-radius:5px 5px 0 0}.sm-dox>li:last-child>a,.sm-dox>li:last-child>*:not(ul) a,.sm-dox>li:last-child>ul,.sm-dox>li:last-child>ul>li:last-child>a,.sm-dox>li:last-child>ul>li:last-child>*:not(ul) a,.sm-dox>li:last-child>ul>li:last-child>ul,.sm-dox>li:last-child>ul>li:last-child>ul>li:last-child>a,.sm-dox>li:last-child>ul>li:last-child>ul>li:last-child>*:not(ul) a,.sm-dox>li:last-child>ul>li:last-child>ul>li:last-child>ul,.sm-dox>li:last-child>ul>li:last-child>ul>li:last-child>ul>li:last-child>a,.sm-dox>li:last-child>ul>li:last-child>ul>li:last-child>ul>li:last-child>*:not(ul) a,.sm-dox>li:last-child>ul>li:last-child>ul>li:last-child>ul>li:last-child>ul,.sm-dox>li:last-child>ul>li:last-child>ul>li:last-child>ul>li:last-child>ul>li:last-child>a,.sm-dox>li:last-child>ul>li:last-child>ul>li:last-child>ul>li:last-child>ul>li:last-child>*:not(ul) a,.sm-dox>li:last-child>ul>li:last-child>ul>li:last-child>ul>li:last-child>ul>li:last-child>ul{-moz-border-radius:0 0 5px 5px;-webkit-border-radius:0;border-radius:0 0 5px 5px}.sm-dox>li:last-child>a.highlighted,.sm-dox>li:last-child>*:not(ul) a.highlighted,.sm-dox>li:last-child>ul>li:last-child>a.highlighted,.sm-dox>li:last-child>ul>li:last-child>*:not(ul) a.highlighted,.sm-dox>li:last-child>ul>li:last-child>ul>li:last-child>a.highlighted,.sm-dox>li:last-child>ul>li:last-child>ul>li:last-child>*:not(ul) a.highlighted,.sm-dox>li:last-child>ul>li:last-child>ul>li:last-child>ul>li:last-child>a.highlighted,.sm-dox>li:last-child>ul>li:last-child>ul>li:last-child>ul>li:last-child>*:not(ul) a.highlighted,.sm-dox>li:last-child>ul>li:last-child>ul>li:last-child>ul>li:last-child>ul>li:last-child>a.highlighted,.sm-dox>li:last-child>ul>li:last-child>ul>li:last-child>ul>li:last-child>ul>li:last-child>*:not(ul) a.highlighted{-moz-border-radius:0;-webkit-border-radius:0;border-radius:0}.sm-dox ul{background:rgba(162,162,162,0.1)}.sm-dox ul a,.sm-dox ul a:focus,.sm-dox ul a:hover,.sm-dox ul a:active{font-size:12px;border-left:8px solid transparent;line-height:36px;text-shadow:none;background-color:white;background-image:none}.sm-dox ul a:hover{background-image:url("tab_a.png");background-repeat:repeat-x;color:white;text-shadow:0 1px 1px black}.sm-dox ul ul a,.sm-dox ul ul a:hover,.sm-dox ul ul a:focus,.sm-dox ul ul a:active{border-left:16px solid transparent}.sm-dox ul ul ul a,.sm-dox ul ul ul a:hover,.sm-dox ul ul ul a:focus,.sm-dox ul ul ul a:active{border-left:24px solid transparent}.sm-dox ul ul ul ul a,.sm-dox ul ul ul ul a:hover,.sm-dox ul ul ul ul a:focus,.sm-dox ul ul ul ul a:active{border-left:32px solid transparent}.sm-dox ul ul ul ul ul a,.sm-dox ul ul ul ul ul a:hover,.sm-dox ul ul ul ul ul a:focus,.sm-dox ul ul ul ul ul a:active{border-left:40px solid transparent}@media(min-width:768px){.sm-dox ul{position:absolute;width:12em}.sm-dox li{float:left}.sm-dox.sm-rtl li{float:right}.sm-dox ul li,.sm-dox.sm-rtl ul li,.sm-dox.sm-vertical li{float:none}.sm-dox a{white-space:nowrap}.sm-dox ul a,.sm-dox.sm-vertical a{white-space:normal}.sm-dox .sm-nowrap>li>a,.sm-dox .sm-nowrap>li>:not(ul) a{white-space:nowrap}.sm-dox{padding:0 10px;background-image:url("tab_b.png");line-height:36px}.sm-dox a span.sub-arrow{top:50%;margin-top:-2px;right:12px;width:0;height:0;border-width:4px;border-style:solid dashed dashed dashed;border-color:#283a5d transparent transparent transparent;background:transparent;-moz-border-radius:0;-webkit-border-radius:0;border-radius:0}.sm-dox a,.sm-dox a:focus,.sm-dox a:active,.sm-dox a:hover,.sm-dox a.highlighted{padding:0 12px;background-image:url("tab_s.png");background-repeat:no-repeat;background-position:right;-moz-border-radius:0!important;-webkit-border-radius:0;border-radius:0!important}.sm-dox a:hover{background-image:url("tab_a.png");background-repeat:repeat-x;color:white;text-shadow:0 1px 1px black}.sm-dox a:hover span.sub-arrow{border-color:white transparent transparent transparent}.sm-dox a.has-submenu{padding-right:24px}.sm-dox li{border-top:0}.sm-dox>li>ul:before,.sm-dox>li>ul:after{content:'';position:absolute;top:-18px;left:30px;width:0;height:0;overflow:hidden;border-width:9px;border-style:dashed dashed solid dashed;border-color:transparent transparent #bbb transparent}.sm-dox>li>ul:after{top:-16px;left:31px;border-width:8px;border-color:transparent transparent #fff transparent}.sm-dox ul{border:1px solid #bbb;padding:5px 0;background:#fff;-moz-border-radius:5px!important;-webkit-border-radius:5px;border-radius:5px!important;-moz-box-shadow:0 5px 9px rgba(0,0,0,0.2);-webkit-box-shadow:0 5px 9px rgba(0,0,0,0.2);box-shadow:0 5px 9px rgba(0,0,0,0.2)}.sm-dox ul a span.sub-arrow{right:8px;top:50%;margin-top:-5px;border-width:5px;border-color:transparent transparent transparent #555;border-style:dashed dashed dashed solid}.sm-dox ul a,.sm-dox ul a:hover,.sm-dox ul a:focus,.sm-dox ul a:active,.sm-dox ul a.highlighted{color:#555;background-image:none;border:0!important;color:#555;background-image:none}.sm-dox ul a:hover{background-image:url("tab_a.png");background-repeat:repeat-x;color:white;text-shadow:0 1px 1px black}.sm-dox ul a:hover span.sub-arrow{border-color:transparent transparent transparent white}.sm-dox span.scroll-up,.sm-dox span.scroll-down{position:absolute;display:none;visibility:hidden;overflow:hidden;background:#fff;height:36px}.sm-dox span.scroll-up:hover,.sm-dox span.scroll-down:hover{background:#eee}.sm-dox span.scroll-up:hover span.scroll-up-arrow,.sm-dox span.scroll-up:hover span.scroll-down-arrow{border-color:transparent transparent #d23600 transparent}.sm-dox span.scroll-down:hover span.scroll-down-arrow{border-color:#d23600 transparent transparent transparent}.sm-dox span.scroll-up-arrow,.sm-dox span.scroll-down-arrow{position:absolute;top:0;left:50%;margin-left:-6px;width:0;height:0;overflow:hidden;border-width:6px;border-style:dashed dashed solid dashed;border-color:transparent transparent #555 transparent}.sm-dox span.scroll-down-arrow{top:8px;border-style:solid dashed dashed dashed;border-color:#555 transparent transparent transparent}.sm-dox.sm-rtl a.has-submenu{padding-right:12px;padding-left:24px}.sm-dox.sm-rtl a span.sub-arrow{right:auto;left:12px}.sm-dox.sm-rtl.sm-vertical a.has-submenu{padding:10px 20px}.sm-dox.sm-rtl.sm-vertical a span.sub-arrow{right:auto;left:8px;border-style:dashed solid dashed dashed;border-color:transparent #555 transparent transparent}.sm-dox.sm-rtl>li>ul:before{left:auto;right:30px}.sm-dox.sm-rtl>li>ul:after{left:auto;right:31px}.sm-dox.sm-rtl ul a.has-submenu{padding:10px 20px!important}.sm-dox.sm-rtl ul a span.sub-arrow{right:auto;left:8px;border-style:dashed solid dashed dashed;border-color:transparent #555 transparent transparent}.sm-dox.sm-vertical{padding:10px 0;-moz-border-radius:5px;-webkit-border-radius:5px;border-radius:5px}.sm-dox.sm-vertical a{padding:10px 20px}.sm-dox.sm-vertical a:hover,.sm-dox.sm-vertical a:focus,.sm-dox.sm-vertical a:active,.sm-dox.sm-vertical a.highlighted{background:#fff}.sm-dox.sm-vertical a.disabled{background-image:url("tab_b.png")}.sm-dox.sm-vertical a span.sub-arrow{right:8px;top:50%;margin-top:-5px;border-width:5px;border-style:dashed dashed dashed solid;border-color:transparent transparent transparent #555}.sm-dox.sm-vertical>li>ul:before,.sm-dox.sm-vertical>li>ul:after{display:none}.sm-dox.sm-vertical ul a{padding:10px 20px}.sm-dox.sm-vertical ul a:hover,.sm-dox.sm-vertical ul a:focus,.sm-dox.sm-vertical ul a:active,.sm-dox.sm-vertical ul a.highlighted{background:#eee}.sm-dox.sm-vertical ul a.disabled{background:#fff}} \ No newline at end of file +.sm{position:relative;z-index:9999}.sm,.sm ul,.sm li{display:block;list-style:none;margin:0;padding:0;line-height:normal;direction:ltr;text-align:left;-webkit-tap-highlight-color:transparent}.sm-rtl,.sm-rtl ul,.sm-rtl li{direction:rtl;text-align:right}.sm>li>h1,.sm>li>h2,.sm>li>h3,.sm>li>h4,.sm>li>h5,.sm>li>h6{margin:0;padding:0}.sm ul{display:none}.sm li,.sm a{position:relative}.sm a{display:block}.sm a.disabled{cursor:not-allowed}.sm:after{content:"\00a0";display:block;height:0;font:0px/0 serif;clear:both;visibility:hidden;overflow:hidden}.sm,.sm *,.sm *:before,.sm *:after{-moz-box-sizing:border-box;-webkit-box-sizing:border-box;box-sizing:border-box}.sm-dox{background-image:url("tab_b.png")}.sm-dox a,.sm-dox a:focus,.sm-dox a:hover,.sm-dox a:active{padding:0px 12px;padding-right:43px;font-family:"Lucida Grande","Geneva","Helvetica",Arial,sans-serif;font-size:13px;font-weight:bold;line-height:36px;text-decoration:none;text-shadow:0px 1px 1px rgba(255,255,255,0.9);color:#283A5D;outline:none}.sm-dox a:hover{background-image:url("tab_a.png");background-repeat:repeat-x;color:#fff;text-shadow:0px 1px 1px #000}.sm-dox a.current{color:#D23600}.sm-dox a.disabled{color:#bbb}.sm-dox a span.sub-arrow{position:absolute;top:50%;margin-top:-14px;left:auto;right:3px;width:28px;height:28px;overflow:hidden;font:bold 12px/28px monospace !important;text-align:center;text-shadow:none;background:rgba(255,255,255,0.5);border-radius:5px}.sm-dox a.highlighted span.sub-arrow:before{display:block;content:'-'}.sm-dox>li:first-child>a,.sm-dox>li:first-child>:not(ul) a{border-radius:5px 5px 0 0}.sm-dox>li:last-child>a,.sm-dox>li:last-child>*:not(ul) a,.sm-dox>li:last-child>ul,.sm-dox>li:last-child>ul>li:last-child>a,.sm-dox>li:last-child>ul>li:last-child>*:not(ul) a,.sm-dox>li:last-child>ul>li:last-child>ul,.sm-dox>li:last-child>ul>li:last-child>ul>li:last-child>a,.sm-dox>li:last-child>ul>li:last-child>ul>li:last-child>*:not(ul) a,.sm-dox>li:last-child>ul>li:last-child>ul>li:last-child>ul,.sm-dox>li:last-child>ul>li:last-child>ul>li:last-child>ul>li:last-child>a,.sm-dox>li:last-child>ul>li:last-child>ul>li:last-child>ul>li:last-child>*:not(ul) a,.sm-dox>li:last-child>ul>li:last-child>ul>li:last-child>ul>li:last-child>ul,.sm-dox>li:last-child>ul>li:last-child>ul>li:last-child>ul>li:last-child>ul>li:last-child>a,.sm-dox>li:last-child>ul>li:last-child>ul>li:last-child>ul>li:last-child>ul>li:last-child>*:not(ul) a,.sm-dox>li:last-child>ul>li:last-child>ul>li:last-child>ul>li:last-child>ul>li:last-child>ul{border-radius:0 0 5px 5px}.sm-dox>li:last-child>a.highlighted,.sm-dox>li:last-child>*:not(ul) a.highlighted,.sm-dox>li:last-child>ul>li:last-child>a.highlighted,.sm-dox>li:last-child>ul>li:last-child>*:not(ul) a.highlighted,.sm-dox>li:last-child>ul>li:last-child>ul>li:last-child>a.highlighted,.sm-dox>li:last-child>ul>li:last-child>ul>li:last-child>*:not(ul) a.highlighted,.sm-dox>li:last-child>ul>li:last-child>ul>li:last-child>ul>li:last-child>a.highlighted,.sm-dox>li:last-child>ul>li:last-child>ul>li:last-child>ul>li:last-child>*:not(ul) a.highlighted,.sm-dox>li:last-child>ul>li:last-child>ul>li:last-child>ul>li:last-child>ul>li:last-child>a.highlighted,.sm-dox>li:last-child>ul>li:last-child>ul>li:last-child>ul>li:last-child>ul>li:last-child>*:not(ul) a.highlighted{border-radius:0}.sm-dox ul{background:rgba(162,162,162,0.1)}.sm-dox ul a,.sm-dox ul a:focus,.sm-dox ul a:hover,.sm-dox ul a:active{font-size:12px;border-left:8px solid transparent;line-height:36px;text-shadow:none;background-color:white;background-image:none}.sm-dox ul a:hover{background-image:url("tab_a.png");background-repeat:repeat-x;color:#fff;text-shadow:0px 1px 1px #000}.sm-dox ul ul a,.sm-dox ul ul a:hover,.sm-dox ul ul a:focus,.sm-dox ul ul a:active{border-left:16px solid transparent}.sm-dox ul ul ul a,.sm-dox ul ul ul a:hover,.sm-dox ul ul ul a:focus,.sm-dox ul ul ul a:active{border-left:24px solid transparent}.sm-dox ul ul ul ul a,.sm-dox ul ul ul ul a:hover,.sm-dox ul ul ul ul a:focus,.sm-dox ul ul ul ul a:active{border-left:32px solid transparent}.sm-dox ul ul ul ul ul a,.sm-dox ul ul ul ul ul a:hover,.sm-dox ul ul ul ul ul a:focus,.sm-dox ul ul ul ul ul a:active{border-left:40px solid transparent}@media (min-width: 768px){.sm-dox ul{position:absolute;width:12em}.sm-dox li{float:left}.sm-dox.sm-rtl li{float:right}.sm-dox ul li,.sm-dox.sm-rtl ul li,.sm-dox.sm-vertical li{float:none}.sm-dox a{white-space:nowrap}.sm-dox ul a,.sm-dox.sm-vertical a{white-space:normal}.sm-dox .sm-nowrap>li>a,.sm-dox .sm-nowrap>li>:not(ul) a{white-space:nowrap}.sm-dox{padding:0 10px;background-image:url("tab_b.png");line-height:36px}.sm-dox a span.sub-arrow{top:50%;margin-top:-2px;right:12px;width:0;height:0;border-width:4px;border-style:solid dashed dashed dashed;border-color:#283A5D transparent transparent transparent;background:transparent;border-radius:0}.sm-dox a,.sm-dox a:focus,.sm-dox a:active,.sm-dox a:hover,.sm-dox a.highlighted{padding:0px 12px;background-image:url("tab_s.png");background-repeat:no-repeat;background-position:right;border-radius:0 !important}.sm-dox a:hover{background-image:url("tab_a.png");background-repeat:repeat-x;color:#fff;text-shadow:0px 1px 1px #000}.sm-dox a:hover span.sub-arrow{border-color:#fff transparent transparent transparent}.sm-dox a.has-submenu{padding-right:24px}.sm-dox li{border-top:0}.sm-dox>li>ul:before,.sm-dox>li>ul:after{content:'';position:absolute;top:-18px;left:30px;width:0;height:0;overflow:hidden;border-width:9px;border-style:dashed dashed solid dashed;border-color:transparent transparent #bbb transparent}.sm-dox>li>ul:after{top:-16px;left:31px;border-width:8px;border-color:transparent transparent #fff transparent}.sm-dox ul{border:1px solid #bbb;padding:5px 0;background:#fff;border-radius:5px !important;box-shadow:0 5px 9px rgba(0,0,0,0.2)}.sm-dox ul a span.sub-arrow{right:8px;top:50%;margin-top:-5px;border-width:5px;border-color:transparent transparent transparent #555;border-style:dashed dashed dashed solid}.sm-dox ul a,.sm-dox ul a:hover,.sm-dox ul a:focus,.sm-dox ul a:active,.sm-dox ul a.highlighted{color:#555;background-image:none;border:0 !important;color:#555;background-image:none}.sm-dox ul a:hover{background-image:url("tab_a.png");background-repeat:repeat-x;color:#fff;text-shadow:0px 1px 1px #000}.sm-dox ul a:hover span.sub-arrow{border-color:transparent transparent transparent #fff}.sm-dox span.scroll-up,.sm-dox span.scroll-down{position:absolute;display:none;visibility:hidden;overflow:hidden;background:#fff;height:36px}.sm-dox span.scroll-up:hover,.sm-dox span.scroll-down:hover{background:#eee}.sm-dox span.scroll-up:hover span.scroll-up-arrow,.sm-dox span.scroll-up:hover span.scroll-down-arrow{border-color:transparent transparent #D23600 transparent}.sm-dox span.scroll-down:hover span.scroll-down-arrow{border-color:#D23600 transparent transparent transparent}.sm-dox span.scroll-up-arrow,.sm-dox span.scroll-down-arrow{position:absolute;top:0;left:50%;margin-left:-6px;width:0;height:0;overflow:hidden;border-width:6px;border-style:dashed dashed solid dashed;border-color:transparent transparent #555 transparent}.sm-dox span.scroll-down-arrow{top:8px;border-style:solid dashed dashed dashed;border-color:#555 transparent transparent transparent}.sm-dox.sm-rtl a.has-submenu{padding-right:12px;padding-left:24px}.sm-dox.sm-rtl a span.sub-arrow{right:auto;left:12px}.sm-dox.sm-rtl.sm-vertical a.has-submenu{padding:10px 20px}.sm-dox.sm-rtl.sm-vertical a span.sub-arrow{right:auto;left:8px;border-style:dashed solid dashed dashed;border-color:transparent #555 transparent transparent}.sm-dox.sm-rtl>li>ul:before{left:auto;right:30px}.sm-dox.sm-rtl>li>ul:after{left:auto;right:31px}.sm-dox.sm-rtl ul a.has-submenu{padding:10px 20px !important}.sm-dox.sm-rtl ul a span.sub-arrow{right:auto;left:8px;border-style:dashed solid dashed dashed;border-color:transparent #555 transparent transparent}.sm-dox.sm-vertical{padding:10px 0;border-radius:5px}.sm-dox.sm-vertical a{padding:10px 20px}.sm-dox.sm-vertical a:hover,.sm-dox.sm-vertical a:focus,.sm-dox.sm-vertical a:active,.sm-dox.sm-vertical a.highlighted{background:#fff}.sm-dox.sm-vertical a.disabled{background-image:url("tab_b.png")}.sm-dox.sm-vertical a span.sub-arrow{right:8px;top:50%;margin-top:-5px;border-width:5px;border-style:dashed dashed dashed solid;border-color:transparent transparent transparent #555}.sm-dox.sm-vertical>li>ul:before,.sm-dox.sm-vertical>li>ul:after{display:none}.sm-dox.sm-vertical ul a{padding:10px 20px}.sm-dox.sm-vertical ul a:hover,.sm-dox.sm-vertical ul a:focus,.sm-dox.sm-vertical ul a:active,.sm-dox.sm-vertical ul a.highlighted{background:#eee}.sm-dox.sm-vertical ul a.disabled{background:#fff}} diff --git a/keylib/CMakeLists.txt b/keylib/CMakeLists.txt index 6d2a3c7..850dd8e 100644 --- a/keylib/CMakeLists.txt +++ b/keylib/CMakeLists.txt @@ -1,6 +1,6 @@ find_package(OpenSSL 1.1.0 REQUIRED) -add_library(keylib SHARED key6.c iit_asn1.c jks.c utils.c attrcurvespec_asn1.c) +add_library(keylib SHARED key6.c iit_asn1.c jks.c pkcs12.c keystore.c utils.c attrcurvespec_asn1.c) target_link_libraries(keylib PUBLIC dstulib coverage_config OpenSSL::Crypto) if ( CLANG_TIDY_EXE ) @@ -14,5 +14,5 @@ install(TARGETS keylib LIBRARY DESTINATION lib ARCHIVE DESTINATION "lib" RUNTIME DESTINATION "bin") -install(FILES keylib.h key6.h jks.h +install(FILES keylib.h keystore.h key6.h jks.h pkcs12.h DESTINATION "include") diff --git a/keylib/jks.c b/keylib/jks.c index 953e51a..3d1dd86 100644 --- a/keylib/jks.c +++ b/keylib/jks.c @@ -1,5 +1,6 @@ #include "jks.h" +#include "keystore_internal.h" #include "utils.h" #include @@ -19,34 +20,8 @@ static const char pbes1OID[] = "1.3.6.1.4.1.42.2.19.1"; static const char keyProtectorOID[] = "1.3.6.1.4.1.42.2.17.1.1"; -struct jks_st -{ - size_t type; - size_t entryNum; - JKSEntry** entries; -}; - -typedef struct cert_st -{ - char* type; - X509* cert; -} Cert; - -struct jks_entry_st -{ - size_t type; - - // JKS_ENTRY_PRIVATE_KEY only - char* name; - size_t keyMaterialSize; - void* keyMaterial; - size_t pkeyNum; - EVP_PKEY** pkeys; - - // JKS_ENTRY_PRIVATE_KEY & JKS_ENTRY_CERT - size_t certNum; - Cert** certs; -}; +#define JKS_ENTRY_PRIVATE_KEY 1 +#define JKS_ENTRY_CERT 2 static const void* ptrAt(const void* base, size_t shift) { @@ -166,104 +141,31 @@ static int whiteHash(const void* d1, size_t ds1, const void* d2, size_t ds2, voi return ok; } -static Cert* CertNew() -{ - Cert* res = OPENSSL_malloc(sizeof(Cert)); - res->type = NULL; - res->cert = NULL; - return res; -} - -static void CertFree(Cert* cert) -{ - if (cert == NULL) - return; - if (cert->type != NULL) - OPENSSL_free(cert->type); - if (cert->cert != NULL) - X509_free(cert->cert); - OPENSSL_free(cert); -} - -static JKSEntry* JKSEntryNew(size_t type, size_t certNum) -{ - size_t i = 0; - JKSEntry* res = OPENSSL_malloc(sizeof(JKSEntry)); - res->type = type; - res->name = NULL; - res->certNum = certNum; - res->certs = OPENSSL_malloc(certNum * sizeof(Cert*)); - res->pkeyNum = 0; - res->pkeys = NULL; - res->keyMaterial = NULL; - res->keyMaterialSize = 0; - for (i = 0; i < certNum; ++i) - res->certs[i] = NULL; - return res; -} - -static void JKSEntryFree(JKSEntry* entry) -{ - size_t i = 0; - if (entry == NULL) - return; - if (entry->name != NULL) - OPENSSL_free(entry->name); - if (entry->pkeys != NULL) - { - for (i = 0; i < entry->pkeyNum; ++i) - EVP_PKEY_free(entry->pkeys[i]); - OPENSSL_free(entry->pkeys); - } - if (entry->certs != NULL) - { - for (i = 0; i < entry->certNum; ++i) - CertFree(entry->certs[i]); - OPENSSL_free(entry->certs); - } - if (entry->keyMaterial != NULL) - OPENSSL_free(entry->keyMaterial); - OPENSSL_free(entry); -} - -static JKS* JKSNew(size_t type, size_t entryNum) -{ - JKS* res = OPENSSL_malloc(sizeof(JKS)); - size_t i = 0; - res->type = type; - res->entryNum = entryNum; - res->entries = OPENSSL_malloc(entryNum * sizeof(JKSEntry*)); - for (i = 0; i < entryNum; ++i) - res->entries[i] = NULL; - return res; -} - -static const void* parseCert(const void* data, Cert** certPtr) +static const void* parseCert(const void* data, KeyStore* ks, size_t* certPos) { uint16_t typeLength = ntohs(read16(data, 0)); uint32_t dataLength = ntohl(read32(data, sizeof(typeLength) + typeLength)); const unsigned char* dataPtr = ptrAt(data, sizeof(typeLength) + typeLength + sizeof(dataLength)); - char* type = NULL; X509* x509 = NULL; - type = OPENSSL_malloc(typeLength + 1); - copyAt(data, sizeof(typeLength), type, typeLength); - type[typeLength] = '\0'; - x509 = d2i_X509(NULL, &dataPtr, dataLength); if (x509 == NULL) - { - OPENSSL_free(type); return NULL; - } - *certPtr = CertNew(); - (*certPtr)->type = type; - (*certPtr)->cert = x509; + KeyStore* tks = KeyStoreNew(0, 1); + + KeyStoreSetCert(tks, 0, x509); + KeyStoreAppend(ks, tks); + + KeyStoreFree(tks); + + if (certPos != NULL) + ++(*certPos); + return ptrAt(data, sizeof(typeLength) + typeLength + sizeof(dataLength) + dataLength); } -static int fromKeyProtector(const void* data, size_t size, const char* pwd16, size_t pwd16Length, EVP_PKEY*** keys, size_t* numKeys) +static int fromKeyProtector(const void* data, size_t size, const char* pwd16, size_t pwd16Length, KeyStore* ks, size_t* keyPos, size_t* certPos) { const size_t saltLength = 20; const size_t digestLength = 20; @@ -310,108 +212,42 @@ static int fromKeyProtector(const void* data, size_t size, const char* pwd16, si return 0; } - r = keysFromPKCS8(decrypted, encryptedLength, keys, numKeys); + KeyStore* tks = NULL; + + r = keysFromPKCS8(decrypted, encryptedLength, &tks); + + if (r != 0) + { + KeyStoreAppend(ks, tks); + if (keyPos != NULL) + *keyPos += KeyStoreKeyNum(tks); + if (certPos != NULL) + *certPos += KeyStoreCertNum(tks); + } + + KeyStoreFree(tks); OPENSSL_free(decrypted); return r; } -static int fromPBES1(const void* data, size_t size, const void* pwd16, size_t pwd16Length, EVP_PKEY*** keys, size_t* numKeys) +static int fromPBES1(const void* data, size_t size, const void* pwd16, size_t pwd16Length, KeyStore* ks, size_t* keyPos, size_t* certPos) { (void) data; //Unused (void) size; //Unused (void) pwd16; //Unused (void) pwd16Length; //Unused - (void) keys; //Unused - (void) numKeys; //Unused + (void) ks; //Unused + (void) keyPos; //Unused + (void) certPos; //Unused return 0; } -static const void* parseKey(const void* data, JKSEntry** entry) -{ - uint16_t nameLength = ntohs(read16(data, 0)); - uint32_t dataLength = ntohl(read32(data, sizeof(nameLength) + nameLength + 8)); // 8 bytes - 64-bit timestamp - uint32_t certNum = ntohl(read32(data, sizeof(nameLength) + nameLength + 8 + 4 + dataLength)); - const unsigned char* dataPtr = ptrAt(data, sizeof(nameLength) + nameLength + 8 + sizeof(dataLength)); - const unsigned char* certPtr = ptrAt(data, sizeof(nameLength) + nameLength + 8 + sizeof(dataLength) + dataLength + sizeof(certNum)); - size_t i = 0; - - *entry = JKSEntryNew(JKS_ENTRY_PRIVATE_KEY, certNum); - - (*entry)->name = OPENSSL_malloc(nameLength + 1); - copyAt(data, sizeof(nameLength), (*entry)->name, nameLength); - (*entry)->name[nameLength] = '\0'; - - (*entry)->keyMaterialSize = dataLength; - (*entry)->keyMaterial = OPENSSL_memdup(dataPtr, dataLength); - - for (i = 0; i < certNum; ++i) - { - certPtr = parseCert(certPtr, &(*entry)->certs[i]); - if (certPtr == NULL) - { - JKSEntryFree(*entry); - return NULL; - } - } - return certPtr; -} - -static const void* parseEntry(const void* data, JKSEntry** entry) -{ - uint32_t tag = ntohl(read32(data, 0)); - switch (tag) - { - case JKS_ENTRY_PRIVATE_KEY: - return parseKey(ptrAt(data, sizeof(tag)), entry); - case JKS_ENTRY_CERT: - *entry = JKSEntryNew(JKS_ENTRY_CERT, 1); - return parseCert(ptrAt(data, sizeof(tag)), &(*entry)->certs[0]); - } - return NULL; -} - -void JKSFree(JKS* jks) -{ - size_t i = 0; - if (jks == NULL) - return; - if (jks->entries != NULL) - { - for (i = 0; i < jks->entryNum; ++i) - JKSEntryFree(jks->entries[i]); - OPENSSL_free(jks->entries); - } - OPENSSL_free(jks); -} - -size_t JKSType(const JKS* jks) -{ - return jks->type; -} - -size_t JKSEntryNum(const JKS* jks) -{ - return jks->entryNum; -} - -JKSEntry* JKSEntryGet(const JKS* jks, size_t pos) -{ - if (pos < jks->entryNum) - return jks->entries[pos]; - return NULL; -} - -size_t JKSEntryType(const JKSEntry* entry) -{ - return entry->type; -} - -int JKSEntryDecrypt(JKSEntry* entry, const char* password, size_t passSize) +static int decryptKey(const void* data, size_t dataSize, const char* password, size_t passSize, KeyStore* ks, size_t* keyPos, size_t* certPos) { void* pwd16 = NULL; size_t pwd16Length = 0; - const unsigned char* dataPtr = entry->keyMaterial; + const unsigned char* dataPtr = data; X509_SIG* epkInfo = NULL; const X509_ALGOR* algo = NULL; const ASN1_OBJECT* aobj = NULL; @@ -419,13 +255,10 @@ int JKSEntryDecrypt(JKSEntry* entry, const char* password, size_t passSize) ASN1_OBJECT* pbes1 = NULL; const ASN1_OCTET_STRING* keyData = NULL; - if (entry->type != JKS_ENTRY_PRIVATE_KEY) - return 1; - if (toUTF16BE(password, passSize, &pwd16, &pwd16Length) == 0) return 0; - epkInfo = d2i_X509_SIG(NULL, &dataPtr, entry->keyMaterialSize); + epkInfo = d2i_X509_SIG(NULL, &dataPtr, dataSize); if (epkInfo == NULL) { OPENSSL_free(pwd16); @@ -439,7 +272,7 @@ int JKSEntryDecrypt(JKSEntry* entry, const char* password, size_t passSize) if (OBJ_cmp(aobj, keyProtector) == 0) { - if (fromKeyProtector(ASN1_STRING_get0_data(keyData), ASN1_STRING_length(keyData), pwd16, pwd16Length, &entry->pkeys, &entry->pkeyNum) == 0) + if (fromKeyProtector(ASN1_STRING_get0_data(keyData), ASN1_STRING_length(keyData), pwd16, pwd16Length, ks, keyPos, certPos) == 0) { ASN1_OBJECT_free(pbes1); ASN1_OBJECT_free(keyProtector); @@ -450,7 +283,7 @@ int JKSEntryDecrypt(JKSEntry* entry, const char* password, size_t passSize) } else if (OBJ_cmp(aobj, pbes1) == 0) { - if (fromPBES1(ASN1_STRING_get0_data(keyData), ASN1_STRING_length(keyData), pwd16, pwd16Length, &entry->pkeys, &entry->pkeyNum) == 0) + if (fromPBES1(ASN1_STRING_get0_data(keyData), ASN1_STRING_length(keyData), pwd16, pwd16Length, ks, keyPos, certPos) == 0) { ASN1_OBJECT_free(pbes1); ASN1_OBJECT_free(keyProtector); @@ -465,106 +298,88 @@ int JKSEntryDecrypt(JKSEntry* entry, const char* password, size_t passSize) OPENSSL_free(pwd16); X509_SIG_free(epkInfo); - if (entry->pkeys == NULL || entry->pkeyNum == 0) - return 0; - return 1; } -const char* JKSEntryPKeyName(const JKSEntry* entry) -{ - return entry->name; -} - -size_t JKSEntryPKeyNum(const JKSEntry* entry) +static const void* parseKey(const void* data, const char* keyPass, size_t keyPassSize, KeyStore* ks, size_t* keyPos, size_t* certPos) { - return entry->pkeyNum; -} + uint16_t nameLength = ntohs(read16(data, 0)); + uint32_t dataLength = ntohl(read32(data, sizeof(nameLength) + nameLength + 8)); // 8 bytes - 64-bit timestamp + uint32_t certNum = ntohl(read32(data, sizeof(nameLength) + nameLength + 8 + 4 + dataLength)); + const unsigned char* dataPtr = ptrAt(data, sizeof(nameLength) + nameLength + 8 + sizeof(dataLength)); + const unsigned char* certPtr = ptrAt(data, sizeof(nameLength) + nameLength + 8 + sizeof(dataLength) + dataLength + sizeof(certNum)); + size_t i = 0; -const EVP_PKEY* JKSEntryPKey(const JKSEntry* entry, size_t pos) -{ - return entry->pkeys[pos]; -} + if (decryptKey(dataPtr, dataLength, keyPass, keyPassSize, ks, keyPos, certPos) == 0) + return NULL; -size_t JKSEntryCertNum(const JKSEntry* entry) -{ - return entry->certNum; + for (i = 0; i < certNum; ++i) + { + certPtr = parseCert(certPtr, ks, certPos); + if (certPtr == NULL) + return NULL; + } + return certPtr; } -const X509* JKSEntryCert(const JKSEntry* entry, size_t pos) +static const void* parseEntry(const void* data, const char* keyPass, size_t keyPassSize, KeyStore* ks, size_t* keyPos, size_t* certPos) { - if (pos < entry->certNum) - return entry->certs[pos]->cert; + uint32_t tag = ntohl(read32(data, 0)); + switch (tag) + { + case JKS_ENTRY_PRIVATE_KEY: + return parseKey(ptrAt(data, sizeof(tag)), keyPass, keyPassSize, ks, keyPos, certPos); + case JKS_ENTRY_CERT: + return parseCert(ptrAt(data, sizeof(tag)), ks, certPos); + } return NULL; } -const char* JKSEntryCertType(const JKSEntry* entry, size_t pos) -{ - if (pos > entry->certNum) - return NULL; - return entry->certs[pos]->type; -} - -int parseJKS(const void* data, size_t size, const char* password, size_t passSize, JKS** keys) +int parseJKS(const void* data, size_t size, const char* storagePass, size_t storagePassSize, const char* keyPass, size_t keyPassSize, KeyStore** ks) { const size_t digestLength = 20; uint32_t magic = read32(data, 0); uint32_t entries = ntohl(read32(data, sizeof(magic) + 4)); // 4 bytes - 32-bit version const unsigned char* entryPtr = ptrAt(data, sizeof(magic) + 4 + sizeof(entries)); unsigned char digest[digestLength]; - size_t type = 0; size_t i = 0; size_t j = 0; - JKS* res = NULL; - JKSEntry* entry = NULL; void* pwd16 = NULL; size_t pwd16Length = 0; + size_t keyPos = 0; + size_t certPos = 0; (void) size; // Unused // Check MAGIC - switch (magic) - { - case 0xedfeedfe: - type = JKS_TYPE_JKS; - break; - case 0xcececece: - type = JKS_TYPE_JCEKS; - break; - default: - return 0; - } + if (magic != 0xedfeedfe && // JKS + magic != 0xcececece) // JCEKS + return 0; + // Check version if (read32(data, sizeof(magic)) != 0x02000000) // 0x00000002 in BE return 0; - if (toUTF16BE(password, passSize, &pwd16, &pwd16Length) == 0) + if (toUTF16BE(storagePass, storagePassSize, &pwd16, &pwd16Length) == 0) return 0; - res = JKSNew(type, entries); + + *ks = KeyStoreNew(0, 0); // Start from zero + for (i = 0; i < entries; ++i) { - entryPtr = parseEntry(entryPtr, &entry); + entryPtr = parseEntry(entryPtr, keyPass, keyPassSize, *ks, &keyPos, &certPos); if (entryPtr == NULL) break; - res->entries[i] = entry; } + if (entryPtr == NULL) { - JKSFree(res); + KeyStoreFree(*ks); return 0; } - if (i > 0) - { - *keys = JKSNew(type, i); - for (j = 0; j < i; ++j) - { - (*keys)->entries[j] = res->entries[j]; - res->entries[j] = NULL; - } - } - JKSFree(res); if (whiteHash(pwd16, pwd16Length, data, entryPtr - (const unsigned char*)data, digest) == 0) { + KeyStoreFree(*ks); OPENSSL_free(pwd16); return 0; } @@ -572,23 +387,26 @@ int parseJKS(const void* data, size_t size, const char* password, size_t passSiz for (j = 0; j < digestLength; ++j) if (digest[j] != entryPtr[j]) + { + KeyStoreFree(*ks); return 0; + } - return i > 0 ? 1 : 0; + return 1; } -int readJKS(FILE* fp, const char* password, size_t passSize, JKS** keys) +int readJKS(FILE* fp, const char* storagePass, size_t storagePassSize, const char* keyPass, size_t keyPassSize, KeyStore** ks) { int res = 0; BIO* bio = BIO_new_fp(fp, 0); if (!bio) return 0; - res = readJKS_bio(bio, password, passSize, keys); + res = readJKS_bio(bio, storagePass, storagePassSize, keyPass, keyPassSize, ks); BIO_free(bio); return res; } -int readJKS_bio(BIO* bio, const char* password, size_t passSize, JKS** keys) +int readJKS_bio(BIO* bio, const char* storagePass, size_t storagePassSize, const char* keyPass, size_t keyPassSize, KeyStore** ks) { unsigned char buf[1024]; BIO *mem = BIO_new(BIO_s_mem()); @@ -621,7 +439,7 @@ int readJKS_bio(BIO* bio, const char* password, size_t passSize, JKS** keys) BIO_free(mem); return 0; } - res = parseJKS(ptr, bytes, password, passSize, keys); + res = parseJKS(ptr, bytes, storagePass, storagePassSize, keyPass, keyPassSize, ks); BIO_free(mem); return res; } diff --git a/keylib/jks.h b/keylib/jks.h index da61ba9..bda8ef3 100644 --- a/keylib/jks.h +++ b/keylib/jks.h @@ -4,6 +4,8 @@ * @brief Functions for reading keys from Java Key Storage. */ +#include "keystore.h" + #include #include @@ -13,149 +15,42 @@ extern "C" { #endif -/** @typedef JKS - * @brief JKS container handle. - */ -typedef struct jks_st JKS; -/** @typedef JKSEntry - * @brief an element of a JKS container. - */ -typedef struct jks_entry_st JKSEntry; - -/** @fn void JKSFree(JKS* jks) - * @brief destroys JKS data. - * @param jks JKS data; - */ -void JKSFree(JKS* jks); - -/** @def JKS_TYPE_JKS - * @brief JKS in the original format. - */ -#define JKS_TYPE_JKS 0 -/** @def JKS_TYPE_JCEKS - * @brief JKS in the improved fromat. - */ -#define JKS_TYPE_JCEKS 1 - -/** @fn size_t JKSType(const JKS* jks) - * @brief returns JKS type. - * @param jks JKS data. - * @return the type of JKS. JKS_TYPE_JKS - original keystore format, JKS_TYPE_JCEKS - improved format. - */ -size_t JKSType(const JKS* jks); - -/** @fn size_t JKSEntryNum(const JKS* jks) - * @brief returns a number of JKS entries. - * @param jks JKS data. - * @return the number of entries in the store. - */ -size_t JKSEntryNum(const JKS* jks); -/** @fn JKSEntry JKSEntryGet(const JKS* jks, size_t pos) - * @brief returns a pointer to the entry number 'pos'. The first entry is 0. - * @param jks JKS data; - * @param pos entry number starting from 0. - * @return the pointer to the entry. - */ -JKSEntry* JKSEntryGet(const JKS* jks, size_t pos); - -/** @def JKS_ENTRY_PRIVATE_KEY - * @brief private key JKS entry. - */ -#define JKS_ENTRY_PRIVATE_KEY 1 -/** @def JKS_ENTRY_CERT - * @brief certificate JKS entry. - */ -#define JKS_ENTRY_CERT 2 - -/** @fn size_t JKSEntryType(const JKSEntry* entry) - * @brief returns JKS entry type. - * @param entry a pointer to the JKS entry. - * @return the type of the entry. JKS_ENTRY_PRIVATE_KEY - private key material, JKS_ENTRY_CERT - certificate. - */ -size_t JKSEntryType(const JKSEntry* entry); - -/** @fn int JKSEntryDecrypt(JKSEntry* entry, const char* password, size_t passSize) - * @brief decrypts an entry with private key material. Does nothig for other entry types. - * @param entry a pointer to the JKS entry; - * @param password private key encryption password; - * @param passSize password size. - * @return 1 for success, 0 in case of failure. - */ -int JKSEntryDecrypt(JKSEntry* entry, const char* password, size_t passSize); - -/** @fn const char* JKSEntryPKeyName(const JKSEntry* entry) - * @brief returns an alias of a private key. Returns NULL for other entry types. - * @param entry a pointer to the JKS entry. - * @return the alias of the private key or NULL. - */ -const char* JKSEntryPKeyName(const JKSEntry* entry); -/** @fn size_t JKSEntryPKeyNum(const JKSEntry* entry) - * @brief returns a number of private keys in this entry. - * @param entry a pointer to the JKS entry. - * @return the number of private keys. - * @note the entry must be decrypted first. Otherwise, the function returns 0. - */ -size_t JKSEntryPKeyNum(const JKSEntry* entry); -/** @fn const EVP_PKEY* JKSEntryPKey(const JKSEntry* entry, size_t pos) - * @brief returns a pointer to an EVP_PKEY number 'pos'. - * @param entry a pointer to the JKS entry; - * @param pos EVP_PKEY number, starting from 0. - * @return the pointer to the EVP_PKEY. - * @note the entry must be decrypted first. Otherwise, the function returns NULL. - */ -const EVP_PKEY* JKSEntryPKey(const JKSEntry* entry, size_t pos); - -/** @fn size_t JKSEntryCertNum(const JKSEntry* entry) - * @brief returns a number of certificates in this entry. - * @param entry a pointer to the JKS entry. - * @return the number of certificates. - */ -size_t JKSEntryCertNum(const JKSEntry* entry); -/** @fn const X509* JKSEntryCert(const JKSEntry* entry, size_t pos) - * @brief returns a pointer to a certificate number 'pos'. - * @param entry a pointer to the JKS entry; - * @param pos certificate number, starting from 0. - * @return the pointer to the certificate. - */ -const X509* JKSEntryCert(const JKSEntry* entry, size_t pos); -/** @fn const char* JKSEntryCertType(const JKSEntry* entry, size_t pos) - * @brief returns a type of a certificate number 'pos'. - * @param entry a pointer to the JKS entry; - * @param pos certificate number, starting from 0. - * @return the type of the certificate. Usually 'X509'. - */ -const char* JKSEntryCertType(const JKSEntry* entry, size_t pos); - -/** @fn int parseJKS(const void* data, size_t size, const char* password, size_t passSize, JKS** keys) +/** @fn int parseJKS(const void* data, size_t size, const char* storagePass, size_t storagePassSize, const char* keyPass, size_t keyPassSize, KeyStore** ks) * @brief extracts private keys and certs from Java Key Store. * @param data container data; * @param size container data size; - * @param password container password; - * @param passSize password size; - * @param keys JKS handle, extracted keys will be stored here. + * @param storagePass container password; + * @param storagePassSize container password size; + * @param keyPass key password; + * @param keyPassSize key password size; + * @param ks KeyStore pointer outparam. * @return 1 for success, 0 in case of failure. */ -int parseJKS(const void* data, size_t size, const char* password, size_t passSize, JKS** keys); +int parseJKS(const void* data, size_t size, const char* storagePass, size_t storagePassSize, const char* keyPass, size_t keyPassSize, KeyStore** ks); -/** @fn int readJKS(FILE* fp, const char* password, size_t passSize, JKS** keys) +/** @fn int readJKS(FILE* fp, const char* storagePass, size_t storagePassSize, const char* keyPass, size_t keyPassSize, KeyStore** ks) * @brief extracts private keys and certs from Java Key Store file. * @param fp file handle; - * @param password container password; - * @param passSize password size; - * @param keys JKS handle, extracted keys will be stored here. + * @param storagePass container password; + * @param storagePassSize container password size; + * @param keyPass key password; + * @param keyPassSize key password size; + * @param ks KeyStore pointer outparam. * @return 1 for success, 0 in case of failure. */ -int readJKS(FILE* fp, const char* password, size_t passSize, JKS** keys); +int readJKS(FILE* fp, const char* storagePass, size_t storagePassSize, const char* keyPass, size_t keyPassSize, KeyStore** ks); -/** @fn int readJKS_bio(BIO* bio, const char* password, size_t passSize, JKS** keys) +/** @fn int readJKS_bio(BIO* bio, const char* storagePass, size_t storagePassSize, const char* keyPass, size_t keyPassSize, KeyStore** ks) * @brief extracts private keys and certs from Java Key Store using OpenSSL BIO interface. * @param bio OpenSSL BIO; - * @param password container password; - * @param passSize password size; - * @param keys JKS handle, extracted keys will be stored here. + * @param storagePass container password; + * @param storagePassSize container password size; + * @param keyPass key password; + * @param keyPassSize key password size; + * @param ks KeyStore pointer outparam. * @return 1 for success, 0 in case of failure. */ -int readJKS_bio(BIO* bio, const char* password, size_t passSize, JKS** keys); +int readJKS_bio(BIO* bio, const char* storagePass, size_t storagePassSize, const char* keyPass, size_t keyPassSize, KeyStore** ks); #ifdef __cplusplus } diff --git a/keylib/key6.c b/keylib/key6.c index 126daf4..43d2415 100644 --- a/keylib/key6.c +++ b/keylib/key6.c @@ -39,7 +39,7 @@ static void pkdf(const char* password, size_t passSize, unsigned char* key) hash(key, 32, key); } -static int decryptKey6(const void* data, size_t size, const void* pad, size_t padSize, const char* password, size_t passSize, EVP_PKEY*** keys, size_t* numKeys) +static int decryptKey6(const void* data, size_t size, const void* pad, size_t padSize, const char* password, size_t passSize, KeyStore** ks) { gost_ctx ctx; gost_subst_block sbox; @@ -60,12 +60,12 @@ static int decryptKey6(const void* data, size_t size, const void* pad, size_t pa gost_dec(&ctx, source, res, sourceSize / 8); OPENSSL_clear_free(source, sourceSize); - r = keysFromPKCS8(res, resSize, keys, numKeys); + r = keysFromPKCS8(res, resSize, ks); OPENSSL_clear_free(res, resSize); return r; } -int parseKey6(const void* data, size_t size, const char* password, size_t passSize, EVP_PKEY*** keys, size_t* numKeys) +int parseKey6(const void* data, size_t size, const char* password, size_t passSize, KeyStore** ks) { int res = 0; ASN1_OBJECT* correctType = NULL; @@ -93,28 +93,28 @@ int parseKey6(const void* data, size_t size, const char* password, size_t passSi res = decryptKey6(ASN1_STRING_get0_data(store->data), ASN1_STRING_length(store->data), NULL, 0, password, passSize, - keys, numKeys); + ks); else res = decryptKey6(ASN1_STRING_get0_data(store->data), ASN1_STRING_length(store->data), ASN1_STRING_get0_data(store->header->params->pad), ASN1_STRING_length(store->header->params->pad), password, passSize, - keys, numKeys); + ks); IITStore_free(store); return res; } -int readKey6(FILE* fp, const char* password, size_t passSize, EVP_PKEY*** keys, size_t* numKeys) +int readKey6(FILE* fp, const char* password, size_t passSize, KeyStore** ks) { int res = 0; BIO* bio = BIO_new_fp(fp, 0); if (!bio) return 0; - res = readKey6_bio(bio, password, passSize, keys, numKeys); + res = readKey6_bio(bio, password, passSize, ks); BIO_free(bio); return res; } -int readKey6_bio(BIO* bio, const char* password, size_t passSize, EVP_PKEY*** keys, size_t* numKeys) +int readKey6_bio(BIO* bio, const char* password, size_t passSize, KeyStore** ks) { unsigned char buf[1024]; BIO *mem = BIO_new(BIO_s_mem()); @@ -147,7 +147,7 @@ int readKey6_bio(BIO* bio, const char* password, size_t passSize, EVP_PKEY*** ke BIO_free(mem); return 0; } - res = parseKey6(ptr, bytes, password, passSize, keys, numKeys); + res = parseKey6(ptr, bytes, password, passSize, ks); BIO_free(mem); return res; } diff --git a/keylib/key6.h b/keylib/key6.h index 17e08b6..ff487f0 100644 --- a/keylib/key6.h +++ b/keylib/key6.h @@ -4,6 +4,8 @@ * @brief Functions for reading keys from IIT Key-6.dat container. */ +#include "keystore.h" + #include #include @@ -13,39 +15,36 @@ extern "C" { #endif -/** @fn int parseKey6(const void* data, size_t size, const char* password, size_t passSize, EVP_PKEY*** keys, size_t* numKeys) +/** @fn int parseKey6(const void* data, size_t size, const char* password, size_t passSize, KeyStore** ks) * @brief extracts private keys from IIT Key-6.dat container. * @param data container data; * @param size container data size; * @param password container encryption password; * @param passSize password size; - * @param keys a pointer to an array of EVP_PKEY pointers, extracted keys will be stored here; - * @param numKeys a number of extracted keys (usually 1 or 2). + * @param ks KeyStore pointer outparam. * @return 1 for success, 0 in case of failure. */ -int parseKey6(const void* data, size_t size, const char* password, size_t passSize, EVP_PKEY*** keys, size_t* numKeys); +int parseKey6(const void* data, size_t size, const char* password, size_t passSize, KeyStore** ks); -/** @fn int readKey6(FILE* fp, const char* password, size_t passSize, EVP_PKEY*** keys, size_t* numKeys) +/** @fn int readKey6(FILE* fp, const char* password, size_t passSize, KeyStore** ks) * @brief extracts private keys from IIT Key-6.dat container. * @param fp file handle; * @param password container encryption password; * @param passSize password size; - * @param keys a pointer to an array of EVP_PKEY pointers, extracted keys will be stored here; - * @param numKeys a number of extracted keys (usually 1 or 2). + * @param ks KeyStore pointer outparam. * @return 1 for success, 0 in case of failure. */ -int readKey6(FILE* fp, const char* password, size_t passSize, EVP_PKEY*** keys, size_t* numKeys); +int readKey6(FILE* fp, const char* password, size_t passSize, KeyStore** ks); -/** @fn int readKey6_bio(BIO* bio, const char* password, size_t passSize, EVP_PKEY*** keys, size_t* numKeys) +/** @fn int readKey6_bio(BIO* bio, const char* password, size_t passSize, KeyStore** ks) * @brief extracts private keys from IIT Key-6.dat container. * @param bio OpenSSL BIO; * @param password container encryption password; * @param passSize password size; - * @param keys a pointer to an array of EVP_PKEY pointers, extracted keys will be stored here; - * @param numKeys a number of extracted keys (usually 1 or 2). + * @param ks KeyStore pointer outparam. * @return 1 for success, 0 in case of failure. */ -int readKey6_bio(BIO* bio, const char* password, size_t passSize, EVP_PKEY*** keys, size_t* numKeys); +int readKey6_bio(BIO* bio, const char* password, size_t passSize, KeyStore** ks); #ifdef __cplusplus } diff --git a/keylib/keylib.h b/keylib/keylib.h index bb953a5..d10c03a 100644 --- a/keylib/keylib.h +++ b/keylib/keylib.h @@ -2,3 +2,5 @@ #include "key6.h" #include "jks.h" +#include "pkcs12.h" +#include "keystore.h" diff --git a/keylib/keystore.c b/keylib/keystore.c new file mode 100644 index 0000000..2bfbc69 --- /dev/null +++ b/keylib/keystore.c @@ -0,0 +1,122 @@ +#include "keystore_internal.h" +#include "keystore.h" + +#include +#include +#include + +struct KeyStore_st +{ + size_t keyNum; + EVP_PKEY** keys; + size_t certNum; + X509** certs; +}; + +KeyStore* KeyStoreNew(size_t keyNum, size_t certNum) +{ + size_t i = 0; + KeyStore* res = OPENSSL_malloc(sizeof(KeyStore)); + if (keyNum > 0) + { + res->keyNum = keyNum; + res->keys = OPENSSL_malloc(keyNum * sizeof(EVP_PKEY*)); + for (i = 0; i < keyNum; ++i) + res->keys[i] = NULL; + } + else + { + res->keyNum = 0; + res->keys = NULL; + } + if (certNum > 0) + { + res->certNum = certNum; + res->certs = OPENSSL_malloc(certNum * sizeof(X509*)); + for (i = 0; i < certNum; ++i) + res->certs[i] = NULL; + } + else + { + res->certNum = 0; + res->certs = NULL; + } + return res; +} + +void KeyStoreAppend(KeyStore* to, KeyStore* from) +{ + size_t i = 0; + if (from->keyNum > 0) + { + to->keys = OPENSSL_clear_realloc(to->keys, to->keyNum * sizeof(EVP_PKEY*), (to->keyNum + from->keyNum) * sizeof(EVP_PKEY*)); + for (i = 0; i < from->keyNum; ++i) + { + to->keys[to->keyNum + i] = from->keys[i]; + from->keys[i] = NULL; + } + to->keyNum += from->keyNum; + } + if (from->certNum > 0) + { + to->certs = OPENSSL_clear_realloc(to->certs, to->certNum * sizeof(X509*), (to->certNum + from->certNum) * sizeof(X509*)); + for (i = 0; i < from->certNum; ++i) + { + to->certs[to->certNum + i] = from->certs[i]; + from->certs[i] = NULL; + } + to->certNum += from->certNum; + } +} + +void KeyStoreFree(KeyStore* ks) +{ + size_t i = 0; + if (ks->keys != NULL) + { + for (i = 0; i < ks->keyNum; ++i) + EVP_PKEY_free(ks->keys[i]); + OPENSSL_clear_free(ks->keys, ks->keyNum * sizeof(EVP_PKEY*)); + } + if (ks->certs != NULL) + { + for (i = 0; i < ks->certNum; ++i) + X509_free(ks->certs[i]); + OPENSSL_clear_free(ks->certs, ks->certNum * sizeof(X509*)); + } + OPENSSL_clear_free(ks, sizeof(KeyStore)); +} + +size_t KeyStoreKeyNum(const KeyStore* ks) +{ + return ks->keyNum; +} + +size_t KeyStoreCertNum(const KeyStore* ks) +{ + return ks->certNum; +} + +void KeyStoreSetKey(KeyStore* ks, size_t pos, EVP_PKEY* key) +{ + ks->keys[pos] = key; +} + +void KeyStoreSetCert(KeyStore* ks, size_t pos, X509* cert) +{ + ks->certs[pos] = cert; +} + +const EVP_PKEY* KeyStoreGetKey(const KeyStore* ks, size_t pos) +{ + if (pos < ks->keyNum) + return ks->keys[pos]; + return NULL; +} + +const X509* KeyStoreGetCert(const KeyStore* ks, size_t pos) +{ + if (pos < ks->certNum) + return ks->certs[pos]; + return NULL; +} diff --git a/keylib/keystore.h b/keylib/keystore.h new file mode 100644 index 0000000..d3a4dcf --- /dev/null +++ b/keylib/keystore.h @@ -0,0 +1,58 @@ +#pragma once + +/** @file keystore.h + * @brief KeyStore is a container for keys and certificates. + */ + +#include + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/** @typedef KeyStore + * @brief KeyStore container handle. It owns all keys and certificates inside. + */ +typedef struct KeyStore_st KeyStore; + +/** @fn void KeyStoreFree(KeyStore* ks) + * @brief destroys KeyStore data. + * @param ks KeyStore handle; + */ +void KeyStoreFree(KeyStore* ks); + +/** @fn size_t KeyStoreKeyNum(const KeyStore* ks) + * @brief returns a number of entries for keys allocated inside the KeyStore. + * @param ks KeyStore handle. + * @return the number of key entries in the store. + */ +size_t KeyStoreKeyNum(const KeyStore* ks); + +/** @fn size_t KeyStoreCertNum(const KeyStore* ks) + * @brief returns a number of entries for certificates allocated inside the KeyStore. + * @param ks KeyStore handle. + * @return the number of cert entries in the store. + */ +size_t KeyStoreCertNum(const KeyStore* ks); + +/** @fn const EVP_PKEY* KeyStoreGetKey(const KeyStore* ks, size_t pos) + * @brief returns a pointer to the key entry number 'pos'. The first entry is 0. + * @param ks KeyStore handle; + * @param pos key entry number starting from 0. + * @return the pointer to the key entry. + */ +const EVP_PKEY* KeyStoreGetKey(const KeyStore* ks, size_t pos); + +/** @fn const X509* KeyStoreGetCert(const KeyStore* ks, size_t pos) + * @brief returns a pointer to the cert entry number 'pos'. The first entry is 0. + * @param ks KeyStore handle; + * @param pos cert entry number starting from 0. + * @return the pointer to the cert entry. + */ +const X509* KeyStoreGetCert(const KeyStore* ks, size_t pos); + +#ifdef __cplusplus +} +#endif diff --git a/keylib/keystore_internal.h b/keylib/keystore_internal.h new file mode 100644 index 0000000..7c20726 --- /dev/null +++ b/keylib/keystore_internal.h @@ -0,0 +1,18 @@ +#pragma once + +#include "keystore.h" + +#ifdef __cplusplus +extern "C" { +#endif + +KeyStore* KeyStoreNew(size_t keyNum, size_t certNum); + +void KeyStoreAppend(KeyStore* to, KeyStore* from); + +void KeyStoreSetKey(KeyStore* ks, size_t pos, EVP_PKEY* key); +void KeyStoreSetCert(KeyStore* ks, size_t pos, X509* cert); + +#ifdef __cplusplus +} +#endif diff --git a/keylib/pkcs12.c b/keylib/pkcs12.c new file mode 100644 index 0000000..48c5e2b --- /dev/null +++ b/keylib/pkcs12.c @@ -0,0 +1,264 @@ +#include "pkcs12.h" + +#include "keystore_internal.h" + +#include +#include +#include +#include +#include +#include +#include + +static int fromBags(const STACK_OF(PKCS12_SAFEBAG)* bags, const char* password, size_t passSize, KeyStore* ks, size_t* keyPos, size_t* certPos); +static int countKeysCertsInBags(const STACK_OF(PKCS12_SAFEBAG)* bags, const char* password, size_t passSize, size_t* numKeys, size_t* numCerts); + +static int countKeysCertsInBag(const PKCS12_SAFEBAG* bag, const char* password, size_t passSize, size_t* numKeys, size_t* numCerts) +{ + switch (PKCS12_SAFEBAG_get_nid(bag)) + { + case NID_keyBag: + case NID_pkcs8ShroudedKeyBag: + if (numKeys) + ++*numKeys; + break; + case NID_certBag: + if (numCerts) + ++*numCerts; + break; + case NID_safeContentsBag: + return countKeysCertsInBags(PKCS12_SAFEBAG_get0_safes(bag), password, passSize, numKeys, numCerts); + } + return 1; +} + +static int countKeysCertsInBags(const STACK_OF(PKCS12_SAFEBAG)* bags, const char* password, size_t passSize, size_t* numKeys, size_t* numCerts) +{ + int i = 0; + for (i = 0; i < sk_PKCS12_SAFEBAG_num(bags); ++i) + { + if (countKeysCertsInBag(sk_PKCS12_SAFEBAG_value(bags, i), password, passSize, numKeys, numCerts) == 0) + return 0; + } + return 1; +} + +static int countKeysCerts(const STACK_OF(PKCS7)* safes, const char* password, size_t passSize, size_t* numKeys, size_t* numCerts) +{ + STACK_OF(PKCS12_SAFEBAG)* bags = NULL; + PKCS7* pkcs7 = NULL; + int bagNID = 0; + int i = 0; + + for (i = 0; i < sk_PKCS7_num(safes); ++i) + { + pkcs7 = sk_PKCS7_value(safes, i); + if (pkcs7 == NULL) + continue; + bagNID = OBJ_obj2nid(pkcs7->type); + if (bagNID == NID_pkcs7_data) + bags = PKCS12_unpack_p7data(pkcs7); + else if (bagNID == NID_pkcs7_encrypted) + bags = PKCS12_unpack_p7encdata(pkcs7, password, passSize); + else + continue; + if (bags == NULL) + return 0; + + if (countKeysCertsInBags(bags, password, passSize, numKeys, numCerts) == 0) + { + sk_PKCS12_SAFEBAG_pop_free(bags, PKCS12_SAFEBAG_free); + return 0; + } + + sk_PKCS12_SAFEBAG_pop_free(bags, PKCS12_SAFEBAG_free); + } + + return 1; +} + +static int fromBag(const PKCS12_SAFEBAG* bag, const char* password, size_t passSize, KeyStore* ks, size_t* keyPos, size_t* certPos) +{ + EVP_PKEY* pkey = NULL; + PKCS8_PRIV_KEY_INFO* pkcs8; + const PKCS8_PRIV_KEY_INFO* pkcs8c = NULL; + X509* x509 = NULL; + + switch (PKCS12_SAFEBAG_get_nid(bag)) + { + case NID_keyBag: + pkcs8c = PKCS12_SAFEBAG_get0_p8inf(bag); + pkey = EVP_PKCS82PKEY(pkcs8c); + if (pkey == NULL) + return 0; + KeyStoreSetKey(ks, (*keyPos)++, pkey); + break; + case NID_pkcs8ShroudedKeyBag: + pkcs8 = PKCS12_decrypt_skey(bag, password, passSize); + if (pkcs8 == NULL) + return 0; + pkey = EVP_PKCS82PKEY(pkcs8); + if (pkey == NULL) + { + PKCS8_PRIV_KEY_INFO_free(pkcs8); + return 0; + } + KeyStoreSetKey(ks, (*keyPos)++, pkey); + PKCS8_PRIV_KEY_INFO_free(pkcs8); + break; + case NID_certBag: + x509 = PKCS12_SAFEBAG_get1_cert(bag); + if (x509 == NULL) + return 0; + KeyStoreSetCert(ks, (*certPos)++, x509); + break; + case NID_safeContentsBag: + return fromBags(PKCS12_SAFEBAG_get0_safes(bag), password, passSize, ks, keyPos, certPos); + } + return 1; +} + +static int fromBags(const STACK_OF(PKCS12_SAFEBAG)* bags, const char* password, size_t passSize, KeyStore* ks, size_t* keyPos, size_t* certPos) +{ + int i = 0; + for (i = 0; i < sk_PKCS12_SAFEBAG_num(bags); ++i) + { + if (fromBag(sk_PKCS12_SAFEBAG_value(bags, i), password, passSize, ks, keyPos, certPos) == 0) + return 0; + } + return 1; +} + +static int fromSafes(const STACK_OF(PKCS7)* safes, const char* password, size_t passSize, KeyStore* ks, size_t* keyPos, size_t* certPos) +{ + STACK_OF(PKCS12_SAFEBAG)* bags = NULL; + PKCS7* pkcs7 = NULL; + int bagNID = 0; + int i = 0; + + for (i = 0; i < sk_PKCS7_num(safes); ++i) + { + pkcs7 = sk_PKCS7_value(safes, i); + if (pkcs7 == NULL) + continue; + bagNID = OBJ_obj2nid(pkcs7->type); + if (bagNID == NID_pkcs7_data) + bags = PKCS12_unpack_p7data(pkcs7); + else if (bagNID == NID_pkcs7_encrypted) + bags = PKCS12_unpack_p7encdata(pkcs7, password, passSize); + else + continue; + if (bags == NULL) + return 0; + + if (fromBags(bags, password, passSize, ks, keyPos, certPos) == 0) + { + sk_PKCS12_SAFEBAG_pop_free(bags, PKCS12_SAFEBAG_free); + return 0; + } + + sk_PKCS12_SAFEBAG_pop_free(bags, PKCS12_SAFEBAG_free); + } + + return 1; +} + +int parsePKCS12(const void* data, size_t dataSize, const char* password, size_t passSize, KeyStore** ks) +{ + const unsigned char* ptr = data; + PKCS12* pkcs12 = d2i_PKCS12(NULL, &ptr, dataSize); + STACK_OF(PKCS7)* safes = NULL; + size_t numKeys = 0; + size_t numCerts = 0; + size_t keyPos = 0; + size_t certPos = 0; + + if (pkcs12 == NULL) + return 0; + + if (PKCS12_verify_mac(pkcs12, password, passSize) == 0) + { + PKCS12_free(pkcs12); + return 0; + } + + safes = PKCS12_unpack_authsafes(pkcs12); + + if (safes == NULL) + { + PKCS12_free(pkcs12); + return 0; + } + + if (countKeysCerts(safes, password, passSize, &numKeys, &numCerts) == 0 || + (numKeys == 0 && numCerts == 0)) + { + sk_PKCS7_pop_free(safes, PKCS7_free); + PKCS12_free(pkcs12); + return 0; + } + + *ks = KeyStoreNew(numKeys, numCerts); + + if (fromSafes(safes, password, passSize, *ks, &keyPos, &certPos) == 0) + { + KeyStoreFree(*ks); + sk_PKCS7_pop_free(safes, PKCS7_free); + PKCS12_free(pkcs12); + return 0; + } + + sk_PKCS7_pop_free(safes, PKCS7_free); + PKCS12_free(pkcs12); + + return 1; +} + +int readPKCS12(FILE* fp, const char* password, size_t passSize, KeyStore** ks) +{ + int res = 0; + BIO* bio = BIO_new_fp(fp, 0); + if (!bio) + return 0; + res = readPKCS12_bio(bio, password, passSize, ks); + BIO_free(bio); + return res; +} + +int readPKCS12_bio(BIO* bio, const char* password, size_t passSize, KeyStore** ks) +{ + unsigned char buf[1024]; + BIO *mem = BIO_new(BIO_s_mem()); + size_t total = 0; + size_t bytes = 0; + size_t written = 0; + char* ptr = NULL; + int res = 0; + for (;;) + { + if (!BIO_read_ex(bio, buf, sizeof(buf), &bytes)) + { + if (total > 0) + break; + BIO_free(mem); + return 0; + } + if (bytes == 0) + break; + if (!BIO_write_ex(mem, buf, bytes, &written)) + { + BIO_free(mem); + return 0; + } + total += bytes; + } + bytes = BIO_get_mem_data(mem, &ptr); + if (bytes == 0 || ptr == NULL) + { + BIO_free(mem); + return 0; + } + res = parsePKCS12(ptr, bytes, password, passSize, ks); + BIO_free(mem); + return res; +} diff --git a/keylib/pkcs12.h b/keylib/pkcs12.h new file mode 100644 index 0000000..0987889 --- /dev/null +++ b/keylib/pkcs12.h @@ -0,0 +1,50 @@ +#pragma once + +/** @file pkcs12.h + * @brief Functions for reading keys from PKCS#12 container. + */ + +#include "keystore.h" + +#include + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/** @fn int parsePKCS12(const void* data, size_t size, const char* password, size_t passSize, KeyStore** ks) + * @brief extracts private keys from PKCS#12 container. + * @param data container data; + * @param size container data size; + * @param password container encryption password; + * @param passSize password size; + * @param ks KeyStore pointer outparam. + * @return 1 for success, 0 in case of failure. + */ +int parsePKCS12(const void* data, size_t dataSize, const char* password, size_t passSize, KeyStore** ks); + +/** @fn int readPKCS12(FILE* fp, const char* password, size_t passSize, KeyStore** ks) + * @brief extracts private keys from PKCS#12 container. + * @param fp file handle; + * @param password container encryption password; + * @param passSize password size; + * @param ks KeyStore pointer outparam. + * @return 1 for success, 0 in case of failure. + */ +int readPKCS12(FILE* fp, const char* password, size_t passSize, KeyStore** ks); + +/** @fn int readPKCS12_bio(BIO* bio, const char* password, size_t passSize, KeyStore** ks) + * @brief extracts private keys from PKCS#12 container. + * @param bio OpenSSL BIO; + * @param password container encryption password; + * @param passSize password size; + * @param ks KeyStore pointer outparam. + * @return 1 for success, 0 in case of failure. + */ +int readPKCS12_bio(BIO* bio, const char* password, size_t passSize, KeyStore** ks); + +#ifdef __cplusplus +} +#endif diff --git a/keylib/utils.c b/keylib/utils.c index 4acfb38..2e25cb2 100644 --- a/keylib/utils.c +++ b/keylib/utils.c @@ -1,5 +1,7 @@ #include "utils.h" +#include "keystore_internal.h" + #include "attrcurvespec_asn1.h" #include "asn1.h" @@ -7,6 +9,7 @@ #include "key.h" #include "params.h" +#include #include #include #include @@ -257,7 +260,7 @@ static EVP_PKEY* pkeyFromAttributes(const PKCS8_PRIV_KEY_INFO* pkcs8) return res; } -int keysFromPKCS8(const void* data, size_t size, EVP_PKEY*** keys, size_t* numKeys) +int keysFromPKCS8(const void* data, size_t size, KeyStore** ks) { const unsigned char* ptr = data; PKCS8_PRIV_KEY_INFO* pkcs8 = d2i_PKCS8_PRIV_KEY_INFO(NULL, &ptr, size); @@ -278,16 +281,14 @@ int keysFromPKCS8(const void* data, size_t size, EVP_PKEY*** keys, size_t* numKe if (pkey2 == NULL) { - *keys = OPENSSL_malloc(sizeof(EVP_PKEY*)); - (*keys)[0] = pkey1; - *numKeys = 1; + *ks = KeyStoreNew(1, 0); + KeyStoreSetKey(*ks, 0, pkey1); return 1; } - *keys = OPENSSL_malloc(sizeof(EVP_PKEY*) * 2); - (*keys)[0] = pkey1; - (*keys)[1] = pkey2; - *numKeys = 2; + *ks = KeyStoreNew(2, 0); + KeyStoreSetKey(*ks, 0, pkey1); + KeyStoreSetKey(*ks, 1, pkey2); return 1; } diff --git a/keylib/utils.h b/keylib/utils.h index 48702b3..ebcf42c 100644 --- a/keylib/utils.h +++ b/keylib/utils.h @@ -1,7 +1,7 @@ #pragma once -#include +#include "keystore.h" #include -int keysFromPKCS8(const void* data, size_t size, EVP_PKEY*** keys, size_t* numKeys); +int keysFromPKCS8(const void* data, size_t size, KeyStore** ks); diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt index 057999e..feddb65 100644 --- a/tests/CMakeLists.txt +++ b/tests/CMakeLists.txt @@ -24,6 +24,11 @@ target_link_libraries(test_jks PUBLIC coverage_config keylib OpenSSL::Crypto) target_include_directories(test_jks PRIVATE "${CMAKE_SOURCE_DIR}/keylib") add_test(test_jks test_jks) +add_executable(test_pkcs12 pkcs12.cpp) +target_link_libraries(test_pkcs12 PUBLIC coverage_config keylib OpenSSL::Crypto) +target_include_directories(test_pkcs12 PRIVATE "${CMAKE_SOURCE_DIR}/keylib") +add_test(test_pkcs12 test_pkcs12) + set_source_files_properties(openssl.cnf PROPERTIES GENERATED TRUE) configure_file(openssl.cnf.in openssl.cnf ESCAPE_QUOTES @ONLY) configure_file(private1.pem private1.pem COPYONLY) @@ -32,4 +37,5 @@ configure_file(public1.pem public1.pem COPYONLY) configure_file(public2.pem public2.pem COPYONLY) configure_file(cms.pem cms.pem COPYONLY) configure_file(Key-6.dat Key-6.dat COPYONLY) +configure_file(Key-6.pfx Key-6.pfx COPYONLY) configure_file(key.jks key.jks COPYONLY) diff --git a/tests/Key-6.pfx b/tests/Key-6.pfx new file mode 100644 index 0000000..3ce1432 Binary files /dev/null and b/tests/Key-6.pfx differ diff --git a/tests/jks.cpp b/tests/jks.cpp index a651eec..9ccfd7a 100644 --- a/tests/jks.cpp +++ b/tests/jks.cpp @@ -1,4 +1,5 @@ #include "jks.h" +#include "keystore.h" #include #include @@ -27,39 +28,19 @@ void testJKS(const std::string& file, const std::string& storagePass, const std: auto* fp = fopen(file.c_str(), "r"); if (fp == nullptr) throw std::runtime_error("testJKS: failed to open '" + file + "'. " + strerror(errno)); - JKS* jks = nullptr; - if (readJKS(fp, storagePass.c_str(), storagePass.length(), &jks) == 0) + KeyStore* ks = nullptr; + if (readJKS(fp, storagePass.c_str(), storagePass.length(), keyPass.c_str(), keyPass.length(), &ks) == 0) throw std::runtime_error("testJKS: failed to read key from '" + file + "'."); fclose(fp); - if (jks == nullptr) + if (ks == nullptr) throw std::runtime_error("testJKS: no keys from '" + file + "'."); - const auto jksType = JKSType(jks); - if (jksType != JKS_TYPE_JKS) - throw std::runtime_error("testJKS: unexpected JKS type. Expected " + std::to_string(JKS_TYPE_JKS) + " (JKS), got " + std::to_string(jksType)); - const auto entryNum = JKSEntryNum(jks); - if (entryNum != 1) - throw std::runtime_error("testJKS: unexpected number of entries. Expected 1, got " + std::to_string(entryNum)); - for (size_t i = 0; i < entryNum; ++i) - { - auto entry = JKSEntryGet(jks, i); - if (entry == nullptr) - throw std::runtime_error("testJKS: empty JKS entry #" + std::to_string(i)); - const auto entryType = JKSEntryType(entry); - if (entryType != JKS_ENTRY_PRIVATE_KEY) - throw std::runtime_error("testJKS: unexpected JKS entry type. Expected " + std::to_string(JKS_ENTRY_PRIVATE_KEY) + " (private key), got " + std::to_string(entryType)); - auto pkeyNum = JKSEntryPKeyNum(entry); - if (pkeyNum != 0) - throw std::runtime_error("testJKS: unexpected number of private keys. Expected 0 (not decrypted), got " + std::to_string(pkeyNum)); - if (JKSEntryDecrypt(entry, keyPass.c_str(), keyPass.length()) == 0) - throw std::runtime_error("testJKS: failed to decrypt private key entry."); - pkeyNum = JKSEntryPKeyNum(entry); - if (pkeyNum != 2) - throw std::runtime_error("testJKS: unexpected number of private keys. Expected 2, got " + std::to_string(pkeyNum)); - const auto certNum = JKSEntryCertNum(entry); - if (certNum != 3) - throw std::runtime_error("testJKS: unexpected number of certificates. Expected 3, got " + std::to_string(certNum)); - } - JKSFree(jks); + const auto keyNum = KeyStoreKeyNum(ks); + if (keyNum != 2) + throw std::runtime_error("testJKS: unexpected number of keys. Expected 2, got " + std::to_string(keyNum)); + const auto certNum = KeyStoreCertNum(ks); + if (certNum != 3) + throw std::runtime_error("testJKS: unexpected number of certs. Expected 3, got " + std::to_string(certNum)); + KeyStoreFree(ks); } } diff --git a/tests/key6.cpp b/tests/key6.cpp index 11d3bec..d27b4ce 100644 --- a/tests/key6.cpp +++ b/tests/key6.cpp @@ -1,4 +1,5 @@ #include "key6.h" +#include "keystore.h" #include #include @@ -27,18 +28,19 @@ void testKey6(const std::string& file, const std::string& password) auto* fp = fopen(file.c_str(), "r"); if (fp == nullptr) throw std::runtime_error("testKey6: failed to open '" + file + "'. " + strerror(errno)); - EVP_PKEY** keys = nullptr; - size_t numKeys = 0; - if (readKey6(fp, password.c_str(), password.length(), &keys, &numKeys) == 0) + KeyStore* ks = nullptr; + if (readKey6(fp, password.c_str(), password.length(), &ks) == 0) throw std::runtime_error("testKey6: failed to read key from '" + file + "'."); - if (keys == nullptr || numKeys == 0) - throw std::runtime_error("testKey6: no keys from '" + file + "'."); - if (numKeys != 2) - throw std::runtime_error("testKey6: '" + file + "' contains two kays, one got."); - for (size_t i = 0; i < numKeys; ++i) - EVP_PKEY_free(keys[i]); - OPENSSL_free(keys); fclose(fp); + if (ks == nullptr) + throw std::runtime_error("testKey6: no keys from '" + file + "'."); + auto keyNum = KeyStoreKeyNum(ks); + if (keyNum != 2) + throw std::runtime_error("testKey6: unexpected number of keys. Expected 2, got " + std::to_string(keyNum) + "."); + const auto certNum = KeyStoreCertNum(ks); + if (certNum != 0) + throw std::runtime_error("testKey6: unexpected number of certs. Expected 0, got " + std::to_string(certNum)); + KeyStoreFree(ks); } } diff --git a/tests/pkcs12.cpp b/tests/pkcs12.cpp new file mode 100644 index 0000000..bf33a15 --- /dev/null +++ b/tests/pkcs12.cpp @@ -0,0 +1,73 @@ +#include "pkcs12.h" +#include "keystore.h" + +#include +#include +#include +#include + +#include +#include +#include + +#include +#include + +namespace +{ + +std::string OPENSSLError() noexcept +{ + std::array buf{}; + ERR_error_string_n(ERR_get_error(), buf.data(), buf.size()); + return buf.data(); +} + +void testPKCS12(const std::string& file, const std::string& pass) +{ + auto* fp = fopen(file.c_str(), "r"); + if (fp == nullptr) + throw std::runtime_error("testPKCS12: failed to open '" + file + "'. " + strerror(errno)); + KeyStore* ks = nullptr; + if (readPKCS12(fp, pass.c_str(), pass.length(), &ks) == 0) + throw std::runtime_error("testPKCS12: failed to read key from '" + file + "'."); + fclose(fp); + if (ks == nullptr) + throw std::runtime_error("testPKCS12: no keys from '" + file + "'."); + const auto keyNum = KeyStoreKeyNum(ks); + if (keyNum != 2) + throw std::runtime_error("testPKCS12: unexpected number of keys. Expected 2, got " + std::to_string(keyNum)); + const auto certNum = KeyStoreCertNum(ks); + if (certNum != 0) + throw std::runtime_error("testPKCS12: unexpected number of certs. Expected 0, got " + std::to_string(certNum)); + KeyStoreFree(ks); +} + +} + +int main() +{ + ERR_load_crypto_strings(); OpenSSL_add_all_algorithms(); + + OPENSSL_init_crypto(OPENSSL_INIT_ENGINE_ALL_BUILTIN | OPENSSL_INIT_LOAD_CONFIG, nullptr); + + if (CONF_modules_load_file("openssl.cnf", nullptr, 0) <= 0) + throw std::runtime_error("main: failed to load config file. " + OPENSSLError()); + + auto* engine = ENGINE_by_id("dstu"); + if (engine == nullptr) + throw std::runtime_error("main: failed to load engine. " + OPENSSLError()); + if (ENGINE_init(engine) == 0) + throw std::runtime_error("main: failed to initialize engine. " + OPENSSLError()); + + ENGINE_set_default(engine, ENGINE_METHOD_ALL); + + testPKCS12("Key-6.pfx", "testplat2021"); + + ENGINE_finish(engine); + ENGINE_free(engine); + + EVP_cleanup(); ERR_free_strings(); CRYPTO_cleanup_all_ex_data(); + + return 0; +}